0

我有这个基本类型:

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

4

3 回答 3

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();您将所有内容放入该实例时typeAinto 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;

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

于 2012-06-22T01:17:43.483 回答
0

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

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

typeA["do"]();
于 2012-06-22T01:08:25.397 回答
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();
于 2012-06-22T01:30:47.573 回答