javascripts如何扩展工作?

How do javascripts extends work?

更新 :@Bergi 在 上的 Post 解释了使用 Reflect.construct 而不仅仅是调用父构造函数的必要性。这将问题转移到 "What's the technical difference between Constructor.call() and Reflect.construct()"。感谢所有的评论。

很长一段时间以来,我一直在通过将新原型的原型设置为要扩展的原型来扩展各种类型。例如。如果我想扩展 class "Person" 我会通过调用 NewType.prototype=Object.create(Person.prototype); 来创建我的扩展原型,例如:

const B = function(){
    return A.call(this);
};

B.prototype = Object.create(A.prototype);

B.prototype.extra_method = function(){
    console.log('hello');
}

最近我注意到这个方法不如 ES6 class extends 有效。例如,如果我想扩展一个内置类型,我只能使用 class extends 关键字来实现。这是为什么?

示例 A(不起作用):

const ArrayExt = function(){
    this.extra_variable = 'hello!';
    return Array.call(this,...arguments); 
}

ArrayExt.prototype = Object.create(Array.prototype);

ArrayExt.prototype.extra_method = function(){
    console.log('Method called!');
}

var inst = new ArrayExt(1,2,3);

inst.push(4);
inst.length == 4 //seems to work right?

inst.extra_method == undefined //not included
inst.extra_variable == undefined //not included (why?)


示例 B(有效):

const ArrayExt = class extends Array{
    constructor(){
        super(...arguments);
        this.extra_variable = 'Hello!';
    }

    extra_method(){
        console.log('I actually am here now!');
    }
};

var inst = new ArrayExt(1,2,3);

inst.push(4);
inst.length == 4 //works
inst.extra_variable == 'Hello!' //works
inst.extra_method() //'I actually am here now!' works

What's the technical difference between Constructor.call() and Reflect.construct()

这是函数对象的不同用法。和Example()new Example()的区别是一样的。

这两个表达式总是做不同的事情,解析为一个对象可能具有的两个不同的内部方法(名为 [[call]][[construct]])。 ES6 刚刚引入了新的函数类型,其中只有一个函数有效(箭头、方法:调用;class 构造函数:构造函数)。从 function 语法创建的函数总是同时启用两者(即使它是不可取的)。