【发布时间】:2020-12-07 12:16:33
【问题描述】:
我已经阅读了大量有关原型的资料,并且总体上了解了继承。 但是,这是困扰我的一件事,我无法弄清楚。
dmitrysoshnikov.com 上有一个简化示例,说明如何使用以下 sn-p 实现原型继承:
// Generic prototype for all letters.
let letter = {
getNumber() {
return this.number;
}
};
let a = {number: 1, __proto__: letter};
let b = {number: 2, __proto__: letter};
// ...
let z = {number: 26, __proto__: letter};
console.log(
a.getNumber(), // 1
b.getNumber(), // 2
z.getNumber(), // 26
);
下图
但是,当我们开始使用实际的继承结构(使用 new 关键字)时,它开始看起来像这样:
我了解它的工作原理。我不明白的是为什么突然我们需要所有子实例都继承自的 Letter.prototype 对象,而不是像上面的第一张图那样拥有它。对我来说,第一个示例似乎没有任何问题。
我能想到的一个潜在原因是,实际方法允许在类中实现静态方法/属性。在上面的示例中,如果您要添加一个静态方法,那么它将是一个添加到 Letter 对象而不是 Letter.prototype 对象的函数。子对象 (a,b,z) 将无法访问该函数。 在第一个示例中,这种功能必须以不同的方式实现,但我仍然认为这不是创建新 Prototype 对象的充分理由。我认为这个静态方法特性可以在没有它的情况下实现。
我错过了什么吗?
编辑:
我认为有很多人试图解释我很感激的事情,但我不确定我的问题 为什么 javascript 运行时被设计为以一种方式而不是另一种方式运行正确理解.
为了说明我的意思,我尝试了几件事。
class Car{
method() {
console.log("hello")
}
}
myCar = new Car();
// First a few tests as expected
myCar.method() // works
console.log(myCar.method === Car.method) // False, JS doesn't work that way, ok...
console.log(myCar.method === Car.prototype.method) // This is how it works, fine...
// How about we move the reference to the method up one level
Car.method = Car.prototype.method
// Delete the reference to it in prototype object,
// Btw. I tried to remove reference to whole prototype but somehow doesn't let me
delete Car.prototype.method
// Change the prototype chain so it links directly to Car and not Car's prototype object
myCar.__proto__ = Car
myCar.method() // Still works!!!
console.log(myCar.method === Car.method) // True !
console.log(myCar.method === Car.prototype.method) // False, we deleted the method property out of Car.prototype
所以,Car.prototype 不再需要,至少 myCar 的执行不需要。
那么为什么该方法进入Car.prototype 而不是Car
那么为什么不用myCar.__proto__ = Car 而不是myCar.__proto__ = Car.prototype?
【问题讨论】:
-
似乎没有继承任何东西,纯属暴力。您不应该访问
__proto__,使用构造函数或Object.create或class使对象继承其他对象。 -
考虑避免使用
__proto__。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… -
是的,我知道不能使用
__proto__。我刚刚从另一个网站复制了一个 sn-p,它演示了它的内部工作原理。我知道 Object.create 会达到同样的效果。 -
在现实生活中,我只会使用
class语法和new关键字来实例化对象。但是,我还是不明白为什么当你创建一个Foo类时,它需要创建两个对象,一个给Foo本身,一个给Foo.prototype。为什么 JavaScript 设计者认为只有 Foo 是不够的,而且你还需要 Foo.prototype 才能有其他对象链接到它(如上面的第一张图)。 -
我们无法回答这个问题。您必须向 Brendan Eich 询问设计决策背后的要点,或者可能隐藏在 history 中。
标签: javascript prototype prototype-programming