ECMAScript 6中的原型链

5

我最近阅读了Dr. Axel Rauschmayer的一篇很好的文章:

http://www.2ality.com/2015/02/es6-classes-final.html

以下代码片段大致描述了从ECMAScript 5的角度来看ECMAScript 6原型链是如何工作的(原始文章的第4.2节):

// ECMAScript 6
class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    ···
}

class ColorPoint extends Point {
    constructor(x, y, color) {
        super(x, y);
        this.color = color;
    }
    ···
}

let cp = new ColorPoint(25, 8, 'green');

ECMAScript 5 中的“底层”视图:

 // ECMAScript 5
 // Instance is allocated here
function Point(x, y) {
    // Performed before entering this constructor:
    this = Object.create(new.target.prototype);

    this.x = x;
    this.y = y;
}
···

function ColorPoint(x, y, color) {
    // Performed before entering this constructor:
    this = uninitialized;

    this = Reflect.construct(Point, [x, y], new.target); // (A)
        // super(x, y);

    this.color = color;
}
Object.setPrototypeOf(ColorPoint, Point);
···

let cp = Reflect.construct( // (B)
             ColorPoint, [25, 8, 'green'],
             ColorPoint);
    // let cp = new ColorPoint(25, 8, 'green');

在上面的代码中,我理解这是有效的:
Object.getPrototypeOf(ColorPoint) === Point  //true

因此:
Object.setPrototypeOf(ColorPoint, Point);

我很难理解为什么这个也是正确的,因为我找不到任何“ES5”的解释:

Object.getPrototypeOf(ColorPoint.prototype) === Point.prototype   // true

也许缺少像这样的一行代码..?
Object.setPrototypeOf(ColorPoint.prototype, Point.prototype);

Thank you all in advance.


效果与使用 Object.setPrototypeOf(...) 相同,它会分配内部的 [[Prototype]] 属性。引擎将直接修改该属性,而无需在 JavaScript 中使用 setPrototypeOf() 表示该步骤。 - Jonathan Lonowski
1
ES6在底层不使用setPrototypeOf,它只是一个引入的方法来标准化已弃用的非标准__proto__特性,出于性能原因,不建议使用它。 - the8472
FYI,Object.setPrototypeOf(ColorPoint, Point); 负责继承 静态 方法。 - Felix Kling
1个回答

5
那个来自ES5视角的“引擎盖下视图”不包含那些行——它们隐藏在...部分中。这段代码的重点是解释与ES5继承有关的差异,这些差异都涉及this初始化、new.targetsuper行为以及构造函数从其他构造函数继承等方面。
原型的基本ES5继承仍然存在,并且像往常一样工作:
ColorPoint.prototype = Object.create(Point.prototype, {
    constructor: {value:ColorPoint, writable:true, enumerable:false, configurable:true}
});
// ... further method definitions

我猜你是指 ColorPoint.prototype。另外,你能告诉我为什么构造函数的属性值被设置为 Point 而不是恢复为 ColorPoint 吗? - stratis
@Konos5:哎呀,当然。非常细心,谢谢你! - Bergi
好的。你能告诉我这段代码在哪里执行吗?一旦遇到extends,它是否会自动调用? - stratis
是的,一旦遇到 extendsObject.create(Point.prototype) 就会发生,但是 ColorPoint 函数实例化和 .prototype 赋值以及 .constructor 属性创建将在类的 constructor(){…} 方法被调用时立即发生。 - Bergi
但实际上,这里顺序并不重要(显然ES5并不能完全描述所有细节)。在ES6中,只有在某些操作过程中出现错误时,操作的顺序才会有影响。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接