如何确保从JavaScript中的原型继承的每个对象都有唯一的ID?
我在JavaScript中有这样一个构造函数:如何确保从JavaScript中的原型继承的每个对象都有唯一的ID?,javascript,inheritance,prototype,Javascript,Inheritance,Prototype,我在JavaScript中有这样一个构造函数: var BaseThing = function() { this.id = generateGuid(); } 正如您所期望的,当您创建一个新的BaseThing时,ID每次都是唯一的 var thingOne = new BaseThing(); var thingTwo = new BaseThing(); console.log(thingOne.id === thingTwo.id); // false 但当我尝试创建从BaseT
var BaseThing = function() {
this.id = generateGuid();
}
正如您所期望的,当您创建一个新的BaseThing时,ID每次都是唯一的
var thingOne = new BaseThing();
var thingTwo = new BaseThing();
console.log(thingOne.id === thingTwo.id); // false
但当我尝试创建从BaseThing继承的对象时,事情变得棘手:
var FancyThing = function() {
this.fanciness = "considerable";
}
FancyThing.prototype = new BaseThing();
var thingOne = new FancyThing();
var thingTwo = new FancyThing();
console.log(thingOne.id === thingTwo.id); // true
这当然是有道理的,因为原型继承的工作方式,但这不是我想要的;我希望ID是唯一的,而不必在从BaseThing继承的每个对象上重新实现它
最好的方法是什么?我自己能想到的唯一解决方案是(a)在每个子构造函数上重新实现id(但这似乎破坏了继承点)或(b)向BaseThing添加某种初始化函数(但我不想担心确保每次创建一个对象时都调用它).问题在于您的孩子没有从父代继承构造函数(函数体)。您可以首先应用parent函数,这将提供所需的效果,而无需重新写入父函数中包含的所有内容。这可以通过使用
.apply
完成
var计数器=0;
函数generateGuid(){return++counter;}
var BaseThing=函数(){
this.id=generateGuid();
}
var thingOne=new BaseThing();
var thingTwo=新的BaseThing();
console.log(thingOne.id==thingTwo.id);//错误的
var FancyThing=函数(){
BaseThing.apply(这个,参数)//inherit
这是“相当大的”;
}
FancyThing.prototype=Object.create(BaseThing.prototype,{constructor:{value:FancyThing,writable:true,configurable:true}});
var thingOne=newfancything();
var thingTwo=新的FancyThing();
console.log(thingOne.id==thingTwo.id);//false
问题在于您的子代没有从父代继承构造函数(函数体)。您可以首先应用parent函数,这将提供所需的效果,而无需重新写入父函数中包含的所有内容。这可以通过使用.apply
完成
var计数器=0;
函数generateGuid(){return++counter;}
var BaseThing=函数(){
this.id=generateGuid();
}
var thingOne=new BaseThing();
var thingTwo=新的BaseThing();
console.log(thingOne.id==thingTwo.id);//错误的
var FancyThing=函数(){
BaseThing.apply(这个,参数)//inherit
这是“相当大的”;
}
FancyThing.prototype=Object.create(BaseThing.prototype,{constructor:{value:FancyThing,writable:true,configurable:true}});
var thingOne=newfancything();
var thingTwo=新的FancyThing();
console.log(thingOne.id==thingTwo.id);//false
是的,做与调用super相当的事情并不是一个坏方法。除了应用,您还可以使用call:
function generateGuid(){
return Math.random();
}
var BaseThing = function() {
this.id = generateGuid();
}
var FancyThing = function() {
BaseThing.call(this);
this.fanciness = "considerable";
}
var o = new FancyThing();
console.log(o);
是的,做一个相当于给超级用户打电话的工作并不是一个坏方法。除了应用,您还可以使用call:
function generateGuid(){
return Math.random();
}
var BaseThing = function() {
this.id = generateGuid();
}
var FancyThing = function() {
BaseThing.call(this);
this.fanciness = "considerable";
}
var o = new FancyThing();
console.log(o);
您可以通过将id属性移动到
BaseThing.prototype
并使用Object.defineProperty
使其“计算”出来,来实现这一点
var BaseThing = function() {
//will define id on prototype
//this.id = generateGuid();
}
Object.defineProperty(BaseThing.prototype, 'id', {
configurable: true,
enumerable: true,
get: function() {
//redefine property on first call
Object.defineProperty(this, 'id', {
configurable: false,
enumerable: true,
value: generateGuid()
})
return this.id
}
})
您可以通过将id属性移动到
BaseThing.prototype
并使用Object.defineProperty
var BaseThing = function() {
//will define id on prototype
//this.id = generateGuid();
}
Object.defineProperty(BaseThing.prototype, 'id', {
configurable: true,
enumerable: true,
get: function() {
//redefine property on first call
Object.defineProperty(this, 'id', {
configurable: false,
enumerable: true,
value: generateGuid()
})
return this.id
}
})
这实际上归结为“如何确保子级调用父级构造函数”。答案是,除了让每个子级在其自己的构造函数中实际调用父级之外,您无法确保这一点。这至少让子类承担了这样的责任,而不是子类的使用者。如何
generateGuid()
工作?它是否知道要为其创建id的对象的类型?也许你可以根据对象的类型传递一个参数并生成特定的id…我想我基本上希望有一个比“每次这样做时都要记住调用父构造函数”更优雅的答案。做“正确的”继承:这实际上归结为“如何确保子代调用父构造函数”。答案是,除了让每个子级在其自己的构造函数中实际调用父级之外,您无法确保这一点。这至少让子类承担了这样的责任,而不是子类的使用者。如何generateGuid()
工作?它是否知道要为其创建id的对象的类型?也许你可以根据对象的类型传递一个参数并生成特定的id…我想我基本上希望有一个比“记住每次调用父构造函数”更优雅的答案。执行“正确”继承:apply
可能比call
更可取,as apply允许您传递一组参数apply
可能比call
更可取,as apply允许您传递一组参数FancyThing.prototype=new BaseThing()代码>应该真正变成FancyThing.prototype=Object.create(BaseThing.prototype,{constructor:{value:FancyThing,writable:true,configurable:true}})
FancyThing.prototype=newbasething()代码>应该真正变成FancyThing.prototype=Object.create(BaseThing.prototype,{constructor:{value:FancyThing,writable:true,configurable:true}})代码>。就结果而言,这是最接近要求的结果,但要实现该功能似乎还有很长的路要走。啊哈,这似乎很有效,谢谢!很明显,我需要了解更多关于属性的信息。从结果来看,这是最接近于所要求的,但这项功能似乎还有很长的路要走。啊哈,这似乎很有效,谢谢!显然,我需要更多地了解房地产。