找不到 Javascript 原型方法覆盖

Javascript prototype method override not found

本文关键字:覆盖 方法 原型 Javascript 找不到      更新时间:2023-09-26

我有这个基本类型:

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

和继承类型类型 B:

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 = 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。你基本上说的是"嘿浏览器,如果你在 Type B 的实例中找不到某些东西,看看它是否在这个 Type A 实例中!

事实证明,在这种情况下

实际上什么都没有,只是当浏览器在该对象本身中找不到该名称的变量时,其原型中的内容最终会被使用。当你调用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;

(对不起,如果你已经知道我刚刚告诉你的一切,但我想我会描述一下事情是如何运作的;)

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

typeA.prototype = {
    "do": function() { ... }
    ...
};
typeA["do"]();
最好

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

你要做的是在设置对象原型 TypeA 之后实例化对象。您正在做的是在创建类型B之后动态添加.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();