2012-06-22 33 views
0

我有这样的基本类型:的Javascript原型方法重写

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

+1

'do'是JavaScript中的保留字。可能相关:p – Corbin

+0

除了使用'='运算符的无效语法,您的代码工作正常。如何发布你的实际代码。或者如果你想发布一个简化的例子,发布一个能够真正说明你的问题的例子。 – 2012-06-22 02:27:32

+0

缩减样本过于简化。问题发生在每次使用'this'关键字的地方。 –

回答

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 =新的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的实例中找不到某些东西,看看它是否在类型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(); 

虽然这是一种冷静,当你明白这是怎么回事在恕我直言,额外的间接层(检查是否在类型A的实例之前查看typeA.prototype中定义的东西)可能不是最好的主意,并且您的代码可能会更清晰,如果你只是这么说:

typeB.prototype = typeA.prototype; 

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

+0

感谢您的详细解释。读完这些内容并返回到我的代码后,我意识到了我的问题。样本过于简化。在方法do中,我使用.each遍历数组。在.each回调中,我使用'this'关键字来引用方法'do'。但'这'是指数组的项目,而不是typeB的实例,因此我的问题。 –

0

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

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

typeA["do"](); 
0

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

你必须做的是在你设置typeA的原型之后实例化对象。你正在做的是动态地添加它们的新功能.do()在创建typeB之后。这是你做到这一点的唯一方法。

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();