覆盖派生的属性

将属性添加到对象时,无论它是否存在于原型中,该属性都会添加到对象本身中。 如果原型中已经有一个同名的属性,该属性将不再影响对象,因为它现在隐藏在对象自己的属性后面。

  1. Rabbit.prototype.teeth = "small";
  2. console.log(killerRabbit.teeth);
  3. // → small
  4. killerRabbit.teeth = "long, sharp, and bloody";
  5. console.log(killerRabbit.teeth);
  6. // → long, sharp, and bloody
  7. console.log(blackRabbit.teeth);
  8. // → small
  9. console.log(Rabbit.prototype.teeth);
  10. // → small

下图简单地描述了代码执行后的情况。其中RabbitObject原型画在了killerRabbit之下,我们可以从原型中找到对象中没有的属性。

覆盖派生的属性 - 图1

覆盖原型中存在的属性是很有用的特性。就像示例展示的那样,我们覆盖了killerRabbitteeth属性,这可以用来描述实例(对象中更为泛化的类的实例)的特殊属性,同时又可以让简单对象从原型中获取标准的值。

覆盖也用于向标准函数和数组原型提供toString方法,与基本对象的原型不同。

  1. console.log(Array.prototype.toString ==
  2. Object.prototype.toString);
  3. // → false
  4. console.log([1, 2].toString());
  5. // → 1,2

调用数组的toString方法后得到的结果与调用.join(",")的结果十分类似,即在数组的每个值之间插入一个逗号。而直接使用数组调用Object.prototype.toString则会产生一个完全不同的字符串。由于Object原型提供的toString方法并不了解数组结构,因此只会简单地输出一对方括号,并在方括号中间输出单词"object"和类型的名称。

  1. console.log(Object.prototype.toString.call([1, 2]));
  2. // → [object Array]