我有这种基本类型:
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中做这类事吗?
答案 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();