2014-10-05 78 views
0

假设我有一个javascript类Library1.B,它从同一个库中的超类继承methodA
假设我想将Library1克隆到Library2中,以便制作我自己的版本,并稍微覆盖Library1.B的继承的methodA以改进它。天真,我阐述了这样做:Javascript - 在克隆库中重写继承的方法

/* Library 1 */ 
var Library1 = {}; 

Library1.A = function() { 
    console.log("A's constructor called"); 
}; 
Library1.A.prototype.methodA = function() { 
    console.log("methodA called with arguments", arguments); 
    //heavy computation 
}; 

Library1.B = function() { 
    Library1.A.call(this); 
    //Set a few other properties exclusive to B 
}; 
Library1.B.prototype = Object.create(Library1.A.prototype); 

/* Library 2 */ 
var Library2 = Library1; 

Library2.B.prototype.methodA = function() { 
    console.log("Before invoking methodA()"); 
    Library1.B.methodA.apply(this, arguments); 
    console.log("After invoking methodA()"); 
}; 

var o1 = new Library1.B(); 
o1.methodA(1, 2, 3); 

var o2 = new Library2.B(); 
o2.methodA(4, 5, 6); 

(的jsfiddle here

预计日志上面:

A's constructor called
methodA called with arguments [1, 2, 3]
A's constructor called
Before invoking methodA()
methodA called with arguments [4, 5, 6]
After invoking methodA()

相反,我得到这样的:

A's constructor called
Before invoking methodA()
Uncaught TypeError: Cannot read property 'apply' of undefined

因此很明显, o1,尽管是用构建的对象0的构造函数(它又调用Library1.A的构造函数),已经使用Library2的覆盖的methodA;它然后在Library1.B.methodA.apply电话崩溃,我想因为Library1.B没有它自己的methodA,而是从Library1.A继承。
我的意思是,当我写Library1.B.methodA实际上是“抬头Library1.B的原型链,直到找到定义methodA,然后调用它this这些arguments”是什么。
什么是实现这一目标的正确方法?

+1

你认为这行做了什么'var Library2 = Library1'? – elclanrs 2014-10-05 12:23:08

+0

我看到你在哪里:我期望'Library2'成为'Library1'的一个*拷贝*,但我想它只是成为对'Library1'的引用,所以在'Library2'上调用的任何东西实际上都会被调用' Library1'?我会尝试编辑小提琴,看看问题是否仍然存在,谢谢你的提高。 – 2014-10-05 12:49:43

+0

好吧,编辑jsFiddle(http://jsfiddle.net/axedre/puposqs5/1/),但仍然没有骰子:与以前一样的错误。 :( – 2014-10-05 12:57:38

回答

1

我编辑你的小提琴是这样的:

/* Library2 */ 
var Library2={}; 

Library2.B = function() { 
    console.log("L2.B's constructor starts") 
    Library1.B.call(this) 
    console.log("L2.B's constructor ends") 
} 

Library2.B.prototype.methodA = function() { 
    console.log("Before invoking methodA()"); 
    Library1.B.prototype.methodA.apply(this, arguments); //ADDED "prototype" 
    console.log("After invoking methodA()"); 
}; 

现在Library2无关1,我们写这是从无到有的成员。另一个区别在于你对methodA的超级调用:你正在寻找L1.B中的方法,该方法是一个构造函数,其下的proto是Function。该构造函数的原型尽管(与原底下的不同)是一个空的对象,其底下是构造函数L1.A的原型,它是方法A所在的地方。所以申请代表团没有任何问题。你只是看着构造函数而不是原始链下的任何对象。

现在有什么比这更简单的? :^ @

+0

谢谢!会'Library1.B.prototype。即使'methodA'不在'B'的直接超类中(即:如果它必须上升n个层次'B - > A - >,methodA'也会向上运行'Library1.B'的原型链。 .. - > X',其中'X'具有'methodA')? – 2014-10-06 11:25:21

+1

那么这已经是整个链条。 Library1.B.prototype的under-proto是Library1.A.prototype,我认为它的under-proto是一个空对象。你可以打印出来并检查。但是,否则,是的,它一直在链条上工作。 – 2014-10-06 11:34:54

+0

好的,谜底:[this](http://jsfiddle.net/axedre/puposqs5/4/)代码有什么问题?这些都在评论中解释过,如果需要,我会发出一个新问题,但我没有找到我可以给它的标题的线索 – 2014-10-06 20:44:29