未找到Javascript原型方法覆盖

时间:2012-06-22 01:04:23

标签: javascript override prototype-programming

我有这种基本类型:

typeA = function () {

};

typeA.prototype = {
  do = function() { alert ("do something"); },
  doMore = function() { this.do(); }
}

和继承的类型typeB:

typeB = function () {

};
typeB .prototype = new typeA();
typeB.prototype.do = function() { alert ("do something else"); };

当我创建一个typeB实例并调用doMore时,我收到一个错误,指出this.do不是一个函数。我可以在Javascript中做这类事吗?

3 个答案:

答案 0 :(得分:1)

这个例子你在找什么?

typeA = function () { };

typeA.prototype = {
  do : function() { alert ("do something"); }, //use : instead of = here
  doMore : function() { this.do(); }
}

typeB = function () { };

typeB.prototype = new typeA();
typeB.prototype.do = function() { alert ("do something else"); };

var instance = new typeB();
instance.doMore();

在声明对象的属性时使用:,在为变量赋值时使用=。 :d

补充说明:

这是有趣的事情发生的地方:

typeB.prototype = new typeA();

当您使用.访问对象的函数或变量时,浏览器首先查看对象本身以查看是否在那里定义了该变量。这就是为什么你可以做这样的事情:

var foo = function() {};
foo.prototype.bar = 3

instance = new foo();
alert( instance.bar ); //alerts 3
instance["bar"] = 55;  //add a variable to the instance object itself
alert( instance.bar ); //alerts 55, instance variable masks prototype variable

这显示了有两种方式可以在某个对象中“存在”。它既可以在对象本身中(也可以通过将this.bar = 55添加到构造函数中来实现),也可以在对象的原型中。

因此,当您说typeB.prototype = new typeA();时,您将typeA的所有内容放入typeB'prototype。你基本上说的是“嘿浏览器,如果你在typeB的实例中找不到东西,看看它是否在这个typeA的实例中!”

事实证明实例中没有任何内容,只是当原型中的内容最终被浏览器无法在 中找到该名称的变量时使用对象本身。当您致电instance.doMore()时,浏览器无法在instance中找到它,因此它会查找typeB.prototype,您只需将其设置为typeA的实例。由于它在 实例中找不到任何名为doMore的内容,因此它会查找原型,最后找到doMore的定义并愉快地叫它。

有一件有趣的事情是,您仍然可以处理实际上在您设置为原型的typeA实例中的事物:

//earlier code the same

foo = new typeA();
typeB.prototype = foo;
foo.do = function() { alert ("do something else"); };
//^^ same as `typeB.prototype.do = function() { alert ("do something else"); };`

var instance = new typeB();
instance.doMore();

虽然当你理解恕我直言的内容时,这很酷,但是额外的间接层(在查看typeA.prototype之前检查是否在typeA的实例中定义了东西)可能不是最好的主意,并且如果你刚才这样说,你的代码可能会更清楚:

typeB.prototype = typeA.prototype;

(对不起,如果你已经知道我刚刚告诉你的所有内容,但我想我会描述事情是如何在幕后工作的;)

答案 1 :(得分:0)

您不能使用单词do,因为它是保留关键字(在do while循环中使用)。但是,你可以试试这个:

typeA.prototype = {
    "do": function() { ... }
    ...
};

typeA["do"]();

答案 2 :(得分:0)

在处理原型时使用构造函数会更好。

您需要做的是在设置typeA的原型之后实例化对象。你正在做的是在创建typeB之后动态添加.do()的新函数。这是你能做到的唯一方法。

function typeA() { };
typeA.prototype = {
    'do': function () { alert("do something"); },
    doMore: function () { this.do(); }
}
function typeB() { };
typeB.prototype = new typeA();
typeB.prototype['do'] = function () { alert('doing from typeB'); };
var b = new typeB();
//
b.do();