标准对象

正则对象

正则表达式是一种处理文本信息的神器,在JavaScript中可以方便的使用正则对象对文本进行处理。JavaScript中声明正则对象可以使用var name = /.../var name = new RegExp("..."),第二种方法个人是不推荐的,要处理一系列的文本转义,正则表达式定以后可以使用.test()方法检验是否有匹配和.exec()方法分组

1
2
3
4
5
6
7
8
var re_test = /\w+@\w+\.\w+/
console.log(re_test) ///\w+@\w+\.\w+/
console.log(re_test.test("avbd@163.com")) //true
console.log(re_test.test("adfasd")) //false

var group_test = /(\w+)@(\w+)\.\w+/
console.log(group_test.exec("avbd@163.com"))
//[ 'avbd@163.com', 'avbd', '163', index: 0, input: 'avbd@163.com' ]

另外,在正则结尾后的/处可以加一些参数,比如加g就是启用全局匹配,调用.exec()会像迭代器一样逐个返回匹配到的值。当匹配完所有值后将返回null
1
2
3
4
5
6
7
8
9
var global_test = /\w+/g
console.log(global_test.exec("avbd@163.com"))
//[ 'avbd', index: 0, input: 'avbd@163.com' ]
console.log(global_test.exec("avbd@163.com"))
//[ '163', index: 5, input: 'avbd@163.com' ]
console.log(global_test.exec("avbd@163.com"))
//[ 'com', index: 9, input: 'avbd@163.com' ]
console.log(global_test.exec("avbd@163.com"))
//null

JSON对象

json是一种超轻量级的数据传递格式,脱胎于JavaScript的对象,将按JSON格式完成的对象序列化成文本便可以在网络中传输,接收到文本后反序列化即可获得原数据
序列化使用JSON.stringify()方法,第一个参数为要序列化的object,第二个参数可以是一个列表,描述哪些属性被序列化(默认全部序列化),也可以是一个输入参数为(key,value)的函数,被序列化的内容是key:value+value+是该函数的返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var json_test = {
name:"qian",
age:20,
skill:"python"
}
json_string = JSON.stringify(json_test)
console.log(typeof(json_string),json_string)
//string {"name":"qian","age":20,"skill":"python"}
console.log(JSON.stringify(json_test,["name","age"]))
//{"name":"qian","age":20}
console.log(JSON.stringify(json_test, function(key,value) {
if (key == "age") {
return value - 1
} else {
return value
}
})) //{"name":"qian","age":19,"skill":"python"}

反序列化使用JSON.parse()方法,输入参数为JSON文本
1
2
json_return = JSON.parse(json_string)
console.log(typeof(json_return),json_return)

面向对象编程

创建对象

面向对象编程是目前编程语言的潮流,JavaScript的面向对象编程方法基于原型链而与C++和python的class-object方法不同。JavaScript可以通过一个对象创立另一个对象,或者通过构造函数创建变量
通过某个对象创建对象时,使用Object.create()方法,传入一个对象可依据传入的对象创建出一个平级的对象(而不是继承的),但是创建出的对象没有任何属性,仅保留了方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
test = {
name:"javascript",
time:0,
use:function (){
this.time ++
return this.time
}
}

var python = Object.create(test)
console.log(python) //{}
python.name = "python"
python.time = 1
console.log(python.use()) //2

另一种可以通过构造函数来创建对象,使用一个内部使用了this的函数并在函数内声明各种属性和方法,使用new function的方法调用
1
2
3
4
5
6
7
8
9
10
11
function createobject(name) {
this.name = name
this.time = 0
this.use = function () {
this.time ++
return this.time
}
}
var golang = new createobject("golang")
console.log(golang) //createobject { name: 'golang', time: 0, use: [Function] }
console.log(golang.use()) //1

原型继承

个人认为JavaScript最有意思的一点就是其原型继承的继承机制,由于JavaScript中没有类,因此继承是由对象到对象的。每个对象都有原型.prototype,该原型可以简单的和class类比,一个对象是由原型创建的,那么将一个对象的原型指向另一个对象就可以说是继承了。
但是如果使用直接使用.prototype = objectname的话,在子对象中添加方法的时候方法就会被添加到父对象中从而修改父类,这是不希望看到的,于是可以指定一个空的且与父对象原型相同的对象(父对象平级的空对象,将其prototype指向父对象的prototype),于是这个对象就具备了父对象的所有方法,但是属性仍是空的。
为了继承属性,需要在子对象的构造函数里使用parentobject.call(this,...)的方法。call将父对象的构造函数中的所有方法和对象的this改为指向子对象,于是父对象的方法和属性被子对象继承且原型链正确,子对象新的方法被定义在那个空对象中,不会改变父对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function createobject(name) {
this.x = name
this.time = 0
this.use = function () {
this.time ++
return this.time
}
}
var golang = new createobject("golang")
console.log(golang) //createobject { x: 'golang', time: 0, use: [Function] }

function inherit(parent,child) {
function F() {
}
F.prototype = parent
child.prototype = F
child.prototype.constructor = child
}
function inherit_test(name) {
createobject.call(this,name)
}
inherit(createobject,inherit_test)
test_object = new inherit_test("a")
console.log(test_object) //inherit_test { x: 'a', time: 0, use: [Function] }

以上的例子中,F()是空对象的构造方法,函数inherit(parent,child)封装了继承的原型链修改部分,子对象构造函数inherit_test(name)中的createobject.call(this,name)则拉取了父对象的所有方法和属性

类继承

没有类这一概念可以说是JavaScript的缺点,因为原型继承大大复杂了继承的实现成本,对对象本身的操作却没有数量级的提升,于是在新的JavaScript语法中,class被引进
类的声明使用class 类名 {方法},有一个特殊的方法叫constructor(),这是类的构造函数,和Python的__init__类似,属性可以在该方法中使用this.属性名 = 值声明。调用类生成对象时与使用构造函数生成类一样,使用var var_name = new class_name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class TestClass {
constructor(name) {
this.name = name
this.usetime = 0
}

useonetime() {
this.usetime ++
console.log(this.usetime)
}
}
var a = new TestClass("javascript")
console.log(a) //TestClass { name: 'javascript', usetime: 0 }
a.useonetime() //1

类的引入方便了继承的实现,在class中实现继承只需要两个操作

  • 在声明类时使用class 类名 extends 父类名 {}即可
  • 在构造函数中使用super()调用父类的构造函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class TestIherit extends TestClass {
    constructor(name,data) {
    super(name)
    this.data = data
    }

    reportdata () {
    console.log(this.data)
    }
    }
    var b = new TestIherit("python",10)
    console.log(b)
    //TestIherit { name: 'python', usetime: 0, data: 10 }
    b.useonetime() //1
    b.reportdata() //10