JavaScript 原型继承这段代码有什么不同吗?

JavaScript prototypal inheritance does this code differs one from the other?

我有一个关于 JS 原型的问题:

如果我有以下构造函数:

function Person(name) {
     if (!(this instanceof Person))
         return new Person(name);
     this.name = name;
}
Person.prototype.sayHello = function() {
    console.log("Hello from " + this.name);
}

这里我有一个方法 sayHello 绑定到 Person 的原型,它的内存效率更高:

function Person(name) {
     if (!(this instanceof Person))
         return new Person(name);
     this.name = name;
     this.sayHello = function() {
        console.log("Hello from " + this.name);
     }
}

一瞥:

原型人物:

非原型人:

如您所见,对 sayHello Function 的引用将在所有创建的人中 "shared",而不仅仅是为每个实例化的人。当 sayHello() 被调用到 那个 特定的人时,只要在 sayHello() 上下文中使用它,this 就会变异以指向正确的人。

现在,另一个变体:

function Person(name) {
     if (!(this instanceof Person))
         return new Person(name);
     this.name = name;
     this.__proto__.sayHello = function() {
        console.log("Hello from " + this.name);
     }
}

并且输出与 Person.prototype.sayHello 相同,这意味着 sayHello 被不同的人共享。

但这两种方法有区别吗?我猜不是,因为:

Person.prototype === bob.__proto__ // true

真的,什么时候应该使用前者(Person.prototype.* 在构造函数之外)而不是后者(this.__proto__.* 在构造函数内部)?

扩展 Felix 的评论。

读取的版本:

this.__proto__.sayHello = function() {
    console.log("Hello from " + this.name);
}

不应使用。

每次调用封闭构造函数时,上面的代码也将是 运行,创建该匿名函数的 new 副本,并覆盖引用目前举办于prototype.

任何恰好包含对该函数先前实例的引用的代码将继续指向该旧版本。

在内存效率方面,它与编写 this.sayHello = function(...) 非常相似,因为 none 个实例实际上共享相同的函数副本。在代码效率方面,它可以说更糟(尽管等同于使用 Person.prototype.sayHello = ...),因为每次调用都需要向上提升原型链。