1

我总是对人们试图将某种形式的经典继承强制到 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包含方法getConst1instanceB包含方法getConst1getConst2,正如您在这个 jsfiddle中看到的那样。

1通过在构造函数中分配原型方法,有效地使用由它创建的闭包。

4

1 回答 1

3

不,这不是原型继承。在真正的原型继承中,原型的更改出现在依赖该原型的对象中。在您的示例中,它们没有,因为它们只是被复制的。

我并不是说在某些情况下它可能不是另一种有用的继承形式,但它不是原型。从某种意义上说,我什至不确定它是否是继承,尽管我认为无论哪种方式都可以争论,但无论如何都没关系。

这是添加到原型的示例:

function Parent() {
}
Parent.prototype.foo = function() {
  display("foo!");
};

function Child() {
}
Child.prototype = new Parent();

var c = new Child();

display("[before] typeof c.foo === '" + typeof c.foo + "'");
// shows "[before] typeof c.foo === 'function'"
display("[before] typeof c.bar === '" + typeof c.bar + "'");
// shows "[before] typeof c.bar === 'undefined'"
display("Note that c.bar is currently undefined");

Parent.prototype.bar = function() {
  display("bar!");
};

display("[after] typeof c.bar === '" + typeof c.bar + "'");
// shows "[after] typeof c.bar === 'function'"
display("Now c.bar is a function");

c.foo();
c.bar();

实时复制

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 using for..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 from Object.prototype. Just a recommendation. Additionally, in your case, it doesn't make sense, because the inheritsFrom only works for Function instances, so you'd want to add it to Function.prototype instead (which is a lot less dangerous).

于 2011-05-04T08:50:50.707 回答