在JS中,对象的创建方式有许多种,new Objec、字面量、构造函数等等,在ES6中提供了采用class关键字来创建对象的方式,这些林林种种的写法各有优劣,但是追根究底都是采用new Object的方式来创建的。Object是JS的内置对象,也是所有对象的起源,那么为什么new一个Object得到的就得到个对象呢?这里使用一个更复杂的例子来说明这个问题。
class Car { constructor(name, speed, price) { this.name = name; this.speed = speed; this.price = price; } addSpeed(_speed) { return this.speed + _speed; } }
上面通过ES6提供的class关键字创建了一个名为Car的类,并且定义了属于这个类的名字、速度和价格的属性,这个类还提供了加速的方法。在class关键字的作用范围内,this指向这个类的原型,所以在其中定义的方法,是属于原型对象的方法,实例化的对象都具有共同的方法。在constructor构造器函数中,this指向构造器,也就是构造函数,在构造器中定义的属性属于实例化对象自身的属性。
let bmw = new Car("bmw", 60, 200000);
代码执行遇到new,首先通过Object创建一个空对象。
然后修改这个空对象的__proto__使其指向构造函数的prototype,那么现在空对象的__proto__指向了addSpeed()方法所在的地方,创建的空对象就能够调用这个方法。
改变类的构造器函数中this的值,现在this的值是刚才创建的空对象。然后执行构造器函数中的代码,传递的实参就是这个新创建对象的属性。
构造器函数运行完成后,会默认实例化对象赋值符号后面的等式有一个返回值,这个返回值就是这个对象整体,然后执行赋值运算,声明的bmw就是一个新的属于Car的对象。
由于在创建过程中先修改空对象的__proto__,然后再执行构造器函数,所以在constructor中调用class中定义的方法是能够执行的。
如果在构造器函数中return了一个值,那么采用new创建对象,构造函数执行完成后返回的就不是整体对象,而是return的值。