Kas*_*per 6 javascript ecmascript-6
我发现我可以像这样扩展 Object:
class MyObject extends Object {}
Run Code Online (Sandbox Code Playgroud)
与此有什么区别并且根本不扩展,如下所示:
class MyObject {}
Run Code Online (Sandbox Code Playgroud)
我问这个的原因是因为我有以下mixin:
const MapMixin = (Base = Object) => class extends Base {
static from(array) {
return new this(Object.assign(...array.map(([key, value]) => ({[key]: value}))));
}
map(...args) {
return this.constructor.from(this.entries().map(...args));
}
entries() {
return Object.entries(this);
}
};
Run Code Online (Sandbox Code Playgroud)
这个 mixin 可以这样使用:
class MyObject extends MapMixin(MyBaseClass) {}
Run Code Online (Sandbox Code Playgroud)
但是如果没有基类,我现在已经指定它然后Object作为默认扩展:
class MyObject extends MapMixin() {}
Run Code Online (Sandbox Code Playgroud)
所以我想知道,这是否实际上与根本不扩展任何内容相同。
我不知道这里的其他答案是否清楚,但区别在于静态继承。
在class关键字之前,JavaScript 中的继承一直非常注重实例继承。没有人(我见过)愿意经历让一个类/构造函数从超类/构造函数继承静态成员的麻烦。更不用说做到这一点的唯一方法是通过非标准__proto__属性。
因此,当我们今天查看一个扩展另一个类的类时,我们会考虑继承在该类的实例之间是如何工作的。例如,extendsObject或什么都没有,都是一样的,因为实例本质上是从Object作为基类继承的。
class A {}
class B extends Object {}
let a = new A()
let b = new B()
// a.__proto__.__proto__ === b.__proto__.__proto__ === Object.prototype
Run Code Online (Sandbox Code Playgroud)
但是,可能不清楚或不太清楚extends关键字的作用不仅仅是为实例设置继承。它还设置了类构造函数之间的继承。所以对于B上面,使用extends也意味着Object.setPrototypeOf(B, Object)B 在后台被调用。所以,例如:
class A {} // A constructor inherits nothing (is a basic Function type)
class B extends Object {} // B inherits from Object
// A.setPrototypeOf === undefined
// B.setPrototypeOf === Object.setPrototypeOf
Run Code Online (Sandbox Code Playgroud)
B, extends Object, 从 继承所有静态方法Object,A而不扩展任何东西,不会。
区别在于B.prototype(或B.prototype.__proto__) - 实例继承自B.__proto__什么,以及- 类构造函数继承自什么。扩展Object与否不会影响prototype实例从其继承的内容或内容,但会影响类的__proto__或静态继承。