以下是一个例子:
var Box = function() {
this.id = generateUniqueId();
};
Box.prototype = {
add:function(parent) {
parent.appendChild(this.elm);
}
};
var NewBox = function() {
this.newThing = true;
};
NewBox.prototype = new Box();
NewBox.prototype.remove = function() {
this.elm.parentNode.removeChild(this.elm);
};
var a = new NewBox();
var b = new NewBox();
alert(a.id); // alerts 0
alert(b.id); // also alerts 0! :@
我想a和b(基本上每次创建NewBox
)都有自己的id
。我理解NewBox
正在使用原型继承,因此继承自id
生成的Box
的单个实例,但我希望每个NewBox
得到自己的id
,而不必在NewBox
构造函数中明确说明。
也许这是不可能的,或者我做错了什么,所以请帮忙!
非常感谢!
答案 0 :(得分:6)
在您的示例中,只有在设置Box
对象时才会执行NewBox.prototype
构造函数。
您可以通过使用Function.prototype.apply
方法调用Box
内的NewBox
构造函数来解决此问题,设置this
值并转发所有参数值,例如:
//..
var NewBox = function() {
Box.apply(this, arguments);
this.newThing = true;
};
//..
var a = new NewBox();
var b = new NewBox();
// assuming your `generateUniqueId` function
// increments a number
alert(a.id); // will alert 1
alert(b.id); // will alert 2
现在,每次调用NewBox
构造函数来创建新的对象实例(new NewBox();
)时,它都会调用Box
函数来应用它的所有逻辑。这将帮助您避免一遍又一遍地重复父构造函数的逻辑。
apply
用于调用“父”构造函数,将this
值设置为NewBox
构造函数创建的对象实例,并传递提供给的所有参数这个功能。
您的示例还显示了一个常见问题,当您通过NewBox.prototype = new Box();
表达继承关系时Box
构造函数被调用且有副作用,此新对象将被初始化并且您的generateUniqueId
函数将首次执行,如果你想避免这种情况,你需要使用临时构造函数,只需要创建一个继承自Box.prototype
的新对象,或者使用新的ECMAScript 5 {{1}用于相同目的的方法,例如:
Object.create
或者:
function inherit(o) {
function Tmp() {}
Tmp.prototype = o;
return new Tmp();
}
//.....
NewBox.prototype = inherit(Box.prototype);
通过这种方式,您可以在不首次运行NewBox.prototype = Object.create(Box.prototype);
构造函数的情况下表达相同的继承层次结构,从而避免可能导致的任何副作用。
最后但并非最不重要的是,每当你替换一个函数的prototype属性时,总是建议你恢复这个新原型对象的Box
属性,否则会指向错误的函数。
在您的示例中,由于您使用constructor
的新实例替换NewBox.prototype
,Box
属性将指向NewBox.prototype.constructor
,(您的实例会受到影响,例如Box
)而不是您期望的a.constructor === Box; // true
,我们需要将其设置回来,例如:
NewBox
您可以将这些细节抽象为函数,就像我在上面的NewBox.prototype = someObject; // as any of the examples above
NewBox.prototype.constructor = NewBox;
函数中所做的那样:
inherit
答案 1 :(得分:2)
也许这是不可能的,或者我做错了什么,所以请帮忙!
你做错了什么。
如果您想要特定于实例的值,请在构造函数中初始化它们,而不是原型。
答案 2 :(得分:1)
Matt Ball有正确的想法。而是尝试:
var Box = (function(){
var numberOfBoxes = 0;
function() {
this.id = numberOfBoxes++;
}
})();
或者,如果您希望所有(不同)类具有唯一ID:
var generateUniqueID = (function(){
var runningCount = 0;
return function (){
return runningCount++;
}
})();
var Box = function() {
this.id = generateUniqueId();
};
var NewBox = function() {
this.id = generateUniqueId();
this.newThing = true;
};