繁体   English   中英

找不到Javascript原型方法重写

[英]Javascript prototype method override not found

我有这个基本类型:

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做这种事情吗?

这个例子是您要找的吗?

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 =新的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(); 你把一切都在该实例typeAtypeB'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();

虽然当您了解IMHO发生的事情时这很酷,但间接的额外层(在查看typeA.prototype之前检查是否在typeA实例中定义了东西)可能不是最好的主意,并且您的代码将如果您只是这样说,可能会更清楚:

typeB.prototype = typeA.prototype;

(对不起,如果您已经知道我刚刚告诉您的所有内容,但是我想我要描述一下事情是如何进行的;)

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

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

typeA["do"]();

最好在使用原型时使用构造函数。

您要做的是在设置对象的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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM