覆盖派生的属性
将属性添加到对象时,无论它是否存在于原型中,该属性都会添加到对象本身中。 如果原型中已经有一个同名的属性,该属性将不再影响对象,因为它现在隐藏在对象自己的属性后面。
Rabbit.prototype.teeth = "small";
console.log(killerRabbit.teeth);
// → small
killerRabbit.teeth = "long, sharp, and bloody";
console.log(killerRabbit.teeth);
// → long, sharp, and bloody
console.log(blackRabbit.teeth);
// → small
console.log(Rabbit.prototype.teeth);
// → small
下图简单地描述了代码执行后的情况。其中Rabbit
和Object
原型画在了killerRabbit
之下,我们可以从原型中找到对象中没有的属性。
覆盖原型中存在的属性是很有用的特性。就像示例展示的那样,我们覆盖了killerRabbit
的teeth
属性,这可以用来描述实例(对象中更为泛化的类的实例)的特殊属性,同时又可以让简单对象从原型中获取标准的值。
覆盖也用于向标准函数和数组原型提供toString
方法,与基本对象的原型不同。
console.log(Array.prototype.toString ==
Object.prototype.toString);
// → false
console.log([1, 2].toString());
// → 1,2
调用数组的toString
方法后得到的结果与调用.join(",")
的结果十分类似,即在数组的每个值之间插入一个逗号。而直接使用数组调用Object.prototype.toString
则会产生一个完全不同的字符串。由于Object
原型提供的toString
方法并不了解数组结构,因此只会简单地输出一对方括号,并在方括号中间输出单词"object"
和类型的名称。
console.log(Object.prototype.toString.call([1, 2]));
// → [object Array]