Javascript 作用域链接继承

Javascript scope chaining inheritance

我是一名学习编程的学生。

我有一个问题。

function a () {

}

a.prototype.prtSomething = function(arg) { console.log(arg); }

function b () {

}

var myObj = new b();

如果我想使用myObj中a的方法,我们使用这段代码。

b.prototype = Object.create(a.prototype);
b.prototype.constructor = b;

这意味着改变作用域链接的目标。但是我们为什么不使用这个代码呢?

b.prototype.__proto__ = a.prototype;

我认为创建和使用新对象一定是有原因的。但我不知道。请教我。谢谢。

But why don't we use this code?

你可以,而且它会起作用,但是:

  1. 改变一个对象的原型通常不是一个好主意并且可能使JavaScript引擎不也优化该对象。

  2. __proto__ 曾经是非标准的(并且仍然在网络浏览器之外)并且在 ES2015 之前没有标准的方法来更改对象的原型。 ES2015 添加了 Object.setPrototypeOf(并添加了 __proto__ 到其仅限网络的附件 B)。

因此,我们通常不会更改 b.prototype 的原型,而是替换它。

(我说 "used to" 是因为我不会用现代 JavaScript 编写代码,如果我想要构造函数的继承层次结构,我会使用 class 语法。)


旁注: 不要使用 __proto__。它的存在纯粹是为了与旧代码向后兼容,未针对浏览器之外的 JavaScript 指定,并且不存在于不从 Object.prototype 继承的对象上。 (例如,如果你做 const x = Object.create(null);,那么 "__proto__" in x 就是 false 并且分配给 x.__proto__ 不会改变它的原型。)

相反,如果您有理由更改对象的原型,请使用 Object.setPrototypeOf:

function A() {
}

A.prototype.prtSomething = function(arg) {
    console.log(arg);
};

function B() {
}
Object.setPrototypeOf(B.prototype, A.prototype);

const myObj = new B();
myObj.prtSomething("x");

另请注意,我已将 a 更改为 A 并将 b 更改为 B 以符合标准 JavaScript 命名(构造函数以一个大写字母)。