22

我试图理解创建和使用对象的“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 方面有更多经验,后一种方法对我来说感觉更舒服(也许这就是足够的理由)。但我觉得原型继承的精神更多地出现在第一种选择中。

哪种方法更符合原型编程的“精神”?还是我完全错过了重点?

4

2 回答 2

15

prototype只是对象具有隐式引用的另一个对象。

当你这样做时:

var obj = Object.create( some_object );

...你是说你想obj尝试从 获取属性some_object,当它们在 上不存在时obj

因此,您的第二个示例将更接近您使用它的方式。使用创建的每个对象都Object.create(Dog)将在其原型链中具有该Dog对象。因此,如果您对 进行更改Dog,则更改将反映在Dog链中的所有对象中。

如果主对象具有与原型对象相同的属性,则该属性将隐藏原型的该属性。一个例子就是null您在 的属性上设置的值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"
                                       }
于 2011-09-26T18:08:14.557 回答
3

原型只是一个对象。

它是另一个对象用作原型的任何对象。

于 2011-09-26T18:06:37.740 回答