作者回复: 这个this实例的确是由父类或祖先类创建的。但它不是“继承”来的,因为“继承”这个说法严格来说在JavaScript中就是原型继承,而这个this不是靠原型继承来“传递到”子类的。
在super()调用之前,当前函数——例如子类的构造器——无法访问this,是它的作用域里面没有this这个名字(因为还没有被创建出来嘛)。而super()调用之后,JavaScript引擎会把this“动态地添加到”作用域中,于是this就能访问了。
这个“动态的添加”其实很简单,因为super是子类向父类调用的,所以显然父类调用结束并退出时的当前作用域(或环境)就是子类的,因此ECMAScript约定在退出super()的时候就把已经创建好的this直接“抄写”给当前环境就可以了。这里大概只有一两行代码,很简单的。^^.
作者回复: x.constructor === Car.prototype.constructor === (new Device()).constructor === Device.prototype.constructor
这个正是因为(new Device())导致的原型继承效果。而且,这种继承方法是ES6之前的标准写法,因为那个时代有且仅有`new`运算会在Car/Device之间维护内部原型继承关系,以确保instanceof运算有效。——instanceof运算是检查Car.[[prototype]]这个内部原型的,而不是检查Car.prototype这个属性。
所以,标准的、完整的在ES6之前实现原型继承的代码“总是(且必然是)”两行,而不是示例中的一行:
```
Car.prototype = new Device();
Car.prototype.constructor = Car;
```
另外,也有一种写法,用于在Car()这个函数内部来维护这个constructor属性。例如:
```
function Car() {
this.constructor = Car; // Or, arguments.callee
...
}
Car.prototype = new Device;
```
作者回复: 不。
ES6提供的并不“仅仅是”方法的简写。这种语法风格声明是的“真正的”对象方法。——在ES6之后,真正的对象方法(Method)是与传统的函数在性质上不完全相同的。
而传统的声明方式,也就是“{foo: function ...}”被理解为“函数类型的对象属性”,它是一个Normal Functions,也就是一般的函数,而并非“ES6规范中的对象方法”。
方法是特殊的函数,就如同ES6中“类”是特殊的函数一样。