您如何处理在其子女之间共享原型参考属性的问题?有没有任何众所周知的模式(除了在构造函数中重新定义属性之外)来解决这个问题?这是一个问题,还是我遗漏了一些关于原型继承的东西?
示例:
var dog =
{
name: "no-name",
paws: ["front-right", "front-left", "back-right", "back-left"]
};
var rex = Object.create(dog);
rex.name = "Rex";
var bingo = Object.create(dog);
bingo.name = "Bingo";
bingo.paws.pop(); //Bingo is just like a dog, but has lost a paw in a tragic accident
console.log(bingo.paws); //["front-right", "front-left", "back-right"]
console.log(rex.paws); //Rex lost a paw too! ["front-right", "front-left", "back-right"]
在研究了原型继承之后,在我看来,在这个范例中编程的“自然”方式是扩展对象,而不是过于依赖于构造函数,而是将它们用作“类”。我在博客上看到的例子(它似乎也与Douglas Crockford的Object.create
一致)或多或少是这样的:
var Dog =
{
name: "no-name",
paws: ["front-right", "front-left", "back-right", "back-left"],
bark: function() { alert("Bark!!"); }
};
//No constructor acting like a "class"
var BigDog = Object.create(Dog);
BigDog.bark = function() { alert("WOLF!!!"); };
var thor = Object.create(BigDog);
thor.name = "Thor";
thor.bark();
构造函数是在新实例上复制或创建新数组的唯一方法吗?这种模式Object.create
“不完整”吗?
感谢您的回答!
答案 0 :(得分:3)
如您所知,对象的原型是一个包含构成该对象的基本属性的对象。与所有对象一样,该原型对象是名称到值的映射。 javascript中的数组(和对象)总是通过引用传递,因此当在原型上调用Object.create时 - 它只是将数组的引用复制到新对象中。正如TheZ在评论中所说,你可以这样做:
function Dog(){
this.paws = ['front-right', 'front-left', 'back-right', 'back-left'];
}
Dog.prototype = {
name: 'no-name',
paws: null
};
现在我们可以创建我们的对象了:
var rex = new Dog();
rex.name = 'Rex';
var bingo = new Dog();
bingo.name = 'Bingo';
bingo.paws.pop();
答案 1 :(得分:2)
您应该查看模块模式
制作一个可以使用的封口,这样你的狗就可以分开了
var dog = function(){
//private
var name = "no-name";
var paws = ["front-right", "front-left", "back-right", "back-left"];
//public
function getName(){
return name;
}
function setName(newName){
name = newName;
}
function getPaws(){
return paws;
}
function pawPain(){
paws.pop();
}
//expose
return{
pawPain: pawPain,
getPaws: getPaws,
getName: getName,
setName: setName
};
};
现在你可以用它来制作新狗了
var rex = new dog();
var bingo = new dog();
rex.pawPain();
console.log(bingo.getPaws());
答案 2 :(得分:-1)
只需要一个构造函数。每个版本都拥有自己的对象副本。
function dog(name) {
this.name = "no-name",
this.paws = ["front-right", "front-left", "back-right", "back-left"]
}
var rex = new dog();
rex.name = "Rex";
var bingo = new dog();
bingo.name = "Bingo";
bingo.paws.pop(); //Bingo is just like a dog, but has lost a paw in a tragic accident
console.log(bingo.paws); //["front-right", "front-left", "back-right"]
console.log(rex.paws); //Rex lost a paw too! ["front-right", "front-left", "back-right"]