Javascript 正在使用Object.create()复制构造函数和新对象
根据我对OOP javascript的有限经验,处理具有不同属性的多个对象的常见方法是使用构造函数,如下所示:Javascript 正在使用Object.create()复制构造函数和新对象,javascript,oop,Javascript,Oop,根据我对OOP javascript的有限经验,处理具有不同属性的多个对象的常见方法是使用构造函数,如下所示: function Animal ( type ) { this.type = type }; Animal.prototype.sayHello = function () { return 'Hi, I am a ' + this.type }; var goat = new Animal( 'Goat' ); 我的理解是,山羊将继承/参考动物的功能 我假设我可以用
function Animal ( type ) {
this.type = type
};
Animal.prototype.sayHello = function () {
return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );
我的理解是,山羊
将继承/参考动物
的功能
我假设我可以用以下对象文字概念复制上述内容:
var Animal = {
type : '',
sayHello : function () {
return 'Hi, I am a ' + this.type
}
}
var goat = Object.create( Animal );
goat.type = 'Goat';
对Animal
的继承在这里丢失了,还是Goat
仍然引用Animal
作为方法
我想知道使用Object.create()
而不是new
复制构造函数/类是否存在任何问题。是否有性能偏移或任何理由继续使用new
如果您有任何建议,我将不胜感激。如果需要澄清,我很乐意补充这个问题
更新对象创建
var Animal = {
sayHello : function () {
return 'Hi, I am a ' + this.type
}
}
var goat = Object.create( Animal, { 'type' : { value: 'goat' } } );
…处理具有不同属性的多个对象的常用方法,但相同的方法将使用构造函数
是的,另一种常见的方法是(如您所见)Object.create
我的理解是,山羊
将继承/参考动物
的功能
不完全是。在new Animal
表达式中,goat
将Animal.prototype
引用的对象指定为其基础原型。与动物
没有直接联系,只与动物原型
有直接联系。(Animal.prototype
通过其constructor
属性引用回到Animal
,但如果有人将新对象分配给Animal.prototype
,该链接可能会断开)
对Animal
的继承在这里丢失了,还是Goat
仍然引用Animal
作为方法
在您的非构造函数示例中,goat
将Animal
作为其底层原型,因此对于goat
本身上未找到的任何属性,JavaScript引擎将查看Animal
以查看它是否拥有它。在您的示例中,这意味着goat
正在使用Animal
中的sayHello
,而不是type
,因为goat
有自己的类型
大致相当于:
function Animal ( type ) {
this.type = type
};
Animal.prototype.sayHello = function () {
return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );
…使用Object.create
设置原型,如下所示:
var animalPrototype = {
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
function createAnimal(type) {
var rv = Object.create(animalPrototype);
rv.type = type;
return rv;
};
var goat = createAnimal( 'Goat' );
请回复您的评论:
在createAnimal
中是否会出现任何问题,包括animalPrototype
,然后调用Object.create(this.animalPrototype)
如果你是这个意思:
function createAnimal(type) {
var animalPrototype = { // Issue #1
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
var rv = Object.create(this.animalPrototype); // Issue #2
rv.type = type;
return rv;
};
var goat = createAnimal( 'Goat' );
…那么是的,有两个问题:
每次调用createAnimal
,您都会创建一个新的animalPrototype
,这会破坏目的,2调用createAnimal
中的此
将是全局对象(松散模式)或未定义的
(严格模式),因此此.animalPrototype
可能不是您想要的表达式
您可以这样做:
function createAnimal(type) {
var rv = Object.create(createAnimal.proto);
rv.type = type;
return rv;
};
createAnimal.proto = {
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
var goat = createAnimal( 'Goat' );
当然,这可能会让人困惑,因为它看起来非常像一个构造函数。+1非常好和客观地总结了正在发生的事情。OP-总之是的,使用Object.create
可以在JavaScript中执行原型继承。它将创建一个新对象,其原型就是您指定的原型。(顺便说一句,我选择了“大多数情况下更喜欢的对象。创建”)@BenjaminGruenbaum:谢谢!我的观点相当平衡。如果我正在创建感觉“优雅”的东西,我会使用构造函数(通过我的浏览器)。但是我一直使用Object.create
,我只需要一个与另一个特定对象基本相同但略有不同的对象。我有一个项目,我们经常这样做,虽然它可以用构造函数来完成,但它会非常笨重。我发现它们都是非常有用的工具。我喜欢JavaScript的灵活性。@T.J.Crowder非常感谢你的回答,它澄清了我的几个问题。我更新了我的问题删除偏好,因此您可能需要更新答案的开头。再次感谢你@再次感谢T.J.克劳德。在createAnimal
中是否会出现任何问题,包括animalPrototype
,然后调用Object.create(this.animalPrototype)
?只是为了组织?也许是个愚蠢的主意。@mikedidthis:请参阅答案末尾的进一步更新。您真的想在所有呼叫站点键入山羊。键入(及更多)?如果你想改变它,重构会更困难。这太可怕了。在有人说“创建工厂”之前,在这种情况下,您只是在做美化的构造函数+原型。@Esailija我添加了一个关于如何填充类型的更新。我很想知道你是如何处理这个问题的。这比我刚才批评的还要糟糕:它仍然在调用站点,在对象外部,甚至更多verbose@Esailija你能否澄清原因,不仅仅是为了我自己的理解,也是为了其他用户?我需要创建多个对象。它们之间唯一的区别是类型
。在下面的答案中,function CreateAnimal(type)
是否更适合您?如有进一步评论,我将不胜感激。谢谢。var a=new Animal(type)
vsvar a=CreateAnimal(type)
?两者都很方便,可以将财产分配放在它们所属的地方。然而,在声明站点上,代码仍然有点难看,您必须显式创建并返回一个对象-当使用普通构造函数时,创建和返回语句是隐式的->这就是为什么您只在普通构造函数中键入this.type=xxx
,但需要在工厂中键入return语句和object.create。