Javascript - 重写克隆库中的继承方法

时间:2014-10-05 12:15:02

标签: javascript oop inheritance override

假设我有一个javascript类Library1.B,它从同一个库中的超类继承methodA
假设我想将Library1克隆到Library2中以制作我自己的版本,并通过略微覆盖Library1.B继承的methodA来改进它。天真地,我开始这样做:

/* 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使用参数[1,2,3]进行调用   一个名为
的构造函数   在调用methodA()之前   方法A使用参数[4,5,6]进行调用   在调用methodA()

之后

相反,我得到了这个:

  

一个名为
的构造函数   在调用methodA()之前   未捕获的TypeError:无法读取属性' apply'未定义的

显然o1,尽管是使用Library1.B构造函数构建的对象(反过来调用Library1.A的构造函数),但已经使用了被覆盖的对象来自methodA的{​​{1}};它会在Library2来电时崩溃,我想因为Library1.B.methodA.apply没有自己的Library1.B,而是从methodA继承了它。 我写Library1.A时的意思实际上是"查找Library1.B.methodA的原型链,直到找到Library1.B的定义,然后在{{1}上调用它使用这些methodA"。
实现这个目标的正确方法是什么?

1 个答案:

答案 0 :(得分: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无关,我们从头开始编写它的成员。另一个区别在于你对方法A的超级调用:你正在寻找L1.B中或上面的方法,这是一个构造函数,它的under-under-proto是Function。虽然构造函数的原型(与原型下不同)是一个空对象,其底层原型是构造函数L1.A的原型,它是methodA所在的位置。因此,申请授权从来没有任何问题。您只是在构造函数中查找而不是原型链下的任何对象。

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