我正在尝试理解创建和使用对象的“JavaScript方式”,我认为我遇到了对对象和原型的误解。
在我开始的一个新项目中,我决定尝试原型继承。我很困惑,如果这意味着我应该创建一个我打算使用的对象,然后使用Object.create()
创建其他对象,例如:
var labrador = {
color: 'golden',
sheds: true,
fetch: function()
{
// magic
}
};
var jindo = Object.create(dog);
jindo.color = 'white';
或者,如果我应该创建一种类,并使用Object.create()
创建该实例。
var Dog = { // Is this class-like thing a prototype?
color: null,
sheds: null,
fetch: function()
{
// magic
}
};
var labrador = Object.create(Dog);
labrador.color = 'golden';
labrador.sheds = true;
var jindo = Object.create(Dog);
jindo.color = 'white';
jindo.sheds = true;
在基于类的OOP方面有更多的经验,后一种方法对我来说感觉更舒服(也许这就足够了)。但我觉得原型继承的精神更像是第一种选择。
哪种方法更多的是原型编程的“精神”?还是我完全忽略了这一点?
答案 0 :(得分:14)
prototype
只是一个对象具有隐式引用的另一个对象。
当你这样做时:
var obj = Object.create( some_object );
...您说obj
要求some_object
尝试从obj
获取属性,而Object.create(Dog)
上的属性不存在。
因此,你的第二个例子将更接近你使用它的方式。使用Dog
创建的每个对象都将在其原型链中具有该Dog
个对象。因此,如果您对Dog
进行了更改,则更改将反映在链中null
的所有对象中。
如果主对象具有与原型对象相同的属性,则该属性为 shadowing 原型的属性。例如,您在Dog
的属性上设置的var lab = Object.create(Dog);
lab.color = 'golden';
值。
如果你这样做:
color
...您现在正在隐藏Dog
上的null
媒体资源,因此您将不再获得Dog
。你不以任何方式改变var colorless_dog = Object.create(Dog);
,所以如果我创建另一个对象:
null
...当访问color
属性时,这个仍然会从原型链中获得colorless_dog.color; // null
值。
colorless_dog.color = 'blue';
colorless_dog.color; // 'blue'
......直到你暗示它:
var lab = Object.create(Dog);
lab.color = 'golden';
lab.sheds = true;
所以给出你的例子:
// labrador // Dog
lab.color---> color:'golden' color:null
lab.sheds---> sheds:true sheds:null
lab.fetch()--------------------------> fetch: function() {
alert( this.color ); // 'golden'
// "this" is a reference to the
// "lab" object, instead of "Dog"
}
......它看起来像这样:
{{1}}
答案 1 :(得分:2)
原型只是一个对象。
这是另一个对象使用的任何对象,因为它是原型。