2

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

我有个问题。

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;

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

4

1 回答 1

3

但是我们为什么不使用这段代码呢?

你可以,它会工作,但是:

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

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

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

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


旁注:不要使用__proto__. 它纯粹是为了向后兼容旧代码,没有为浏览器之外的 JavaScript 指定,并且不存在于不继承自Object.prototype. (例如,如果你这样做了const x = Object.create(null);,那么"__proto__" in xisfalse和分配给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");

另请注意,我已更改aAbB符合标准 JavaScript 命名(构造函数以大写字母开头)。

于 2020-05-29T10:15:58.313 回答