我们可以称之为真正的原型继承吗?
我总是对人们试图将某种形式的经典继承强加到 JavaScript 中的方式感到惊讶。我设计了一种方法,可以在某个对象 b 中继承对象 a 的原型方法,而无需将对象 b 的原型方法添加到对象 a,并且可以使用从 1。现在我很好奇:你会说这真的是原型“继承”吗?这是一个可行的方法吗?这其中有陷阱吗?
下面是一些示例代码:
Object.prototype.inheritsFrom = function(obj){
var prototo = this.prototype,
protofrom = obj.prototype;
for (var l in protofrom) {
if (protofrom.hasOwnProperty(l)){
prototo[l] = protofrom[l];
}
}
}
function Obj1(){
var const1 = 25;
if (!Obj1.prototype.getConst1){
Obj1.prototype.getConst1 = function(){
return const1;
}
}
}
function Obj2(){
var const2 = 50;
if (!Obj2.prototype.getConst2){
Obj2.prototype.getConst2 = function(){
return const2;
}
}
Obj2.inheritsFrom(Obj1);
}
var instanceA = new Obj1,
instanceB = new Obj2;
现在 instanceA
包含方法 getConst1
,instanceB
包含方法 getConst1
和 getConst2
code>,正如您在 这个 jsfiddle 中看到的那样。
1 通过在构造函数中分配原型方法,有效地使用由此创建的闭包。
I'm always flabbergasted by the way people try to force some form of classical inheritance into javascript. I have designed a method to inherit in some object b the prototype methods from object a, without adding prototype methods from object b to object a, and the possibility to use private variables from the object inherited from1. Now I'm curious: would you say this is really prototypal 'inheritance'? Is it a viable method? Are there pittfals to it?
Here's some example code:
Object.prototype.inheritsFrom = function(obj){
var prototo = this.prototype,
protofrom = obj.prototype;
for (var l in protofrom) {
if (protofrom.hasOwnProperty(l)){
prototo[l] = protofrom[l];
}
}
}
function Obj1(){
var const1 = 25;
if (!Obj1.prototype.getConst1){
Obj1.prototype.getConst1 = function(){
return const1;
}
}
}
function Obj2(){
var const2 = 50;
if (!Obj2.prototype.getConst2){
Obj2.prototype.getConst2 = function(){
return const2;
}
}
Obj2.inheritsFrom(Obj1);
}
var instanceA = new Obj1,
instanceB = new Obj2;
Now instanceA
contains method getConst1
, instanceB
contains methods getConst1
and getConst2
, as you can see in this jsfiddle.
1 By assigning the prototype methods in the constructor function, effectively using the closure created by that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,这不是典型的继承。在真正的原型继承中,对原型的更改出现在依赖该原型的对象中。在您的示例中,它们没有,因为它们只是被复制。
我并不是说在某些情况下它可能不是另一种有用的继承形式,但它不是典型的。从某种意义上说,我什至不确定它是继承,尽管我认为人们可以以任何一种方式争论它,但无论如何这并不重要。
下面是添加到原型的示例:
Live copy
请注意,这不是一个晦涩的案例。毕竟,您自己的代码依赖于对
Object.prototype
的更改反映在已从其派生的其他事物(Function
)中。离题:强烈建议不要向
Object.prototype
添加任何内容。它会破坏大量假设在{}
上使用for..in
不会产生任何属性的代码。在您能够可靠地将添加标记为不可枚举之前(ECMAScript5 现在提供了一种方法来做到这一点,但大多数实现还没有),请远离Object.prototype
。只是一个推荐。此外,在您的情况下,它没有意义,因为inheritsFrom
仅适用于Function
实例,因此您需要将其添加到Function。代替原型(这样危险性要小得多)。
No, that's not prototypical inheritance. In true prototypical inheritance, changes to the prototype appear in the objects that rely on that prototype. In your example, they don't, because they're only copied.
I'm not saying it may not be another useful form of inheritance for some situations, but it's not prototypical. In some sense I'm not even sure it's inheritance, although I think one could argue it either way and it doesn't really matter regardless.
Here's an example of adding to the prototype:
Live copy
Note that this is not an obscure case. After all, your own code relies on changes to
Object.prototype
being reflected in the other things (Function
) that have already derived from it.Off-topic: Strongly recommend never adding anything to
Object.prototype
. It will break a huge amount of code that assumes that usingfor..in
on a{}
would yield no properties. Until you can reliably mark additions as non-enumerable (ECMAScript5 now provides a way to do that, but most implementations don't have it yet), just stay away fromObject.prototype
. Just a recommendation. Additionally, in your case, it doesn't make sense, because theinheritsFrom
only works forFunction
instances, so you'd want to add it toFunction.prototype
instead (which is a lot less dangerous).