JavaScript 规定,每个函数都有一个prototype属性,指向一个对象。
function f() {}
typeof f.prototype // "object"
复制代码
函数f
默认具有prototype
属性,指向一个对象。
对于构造函数来说,生成实例的时候,该属性会自动成为实例对象的原型。
function Animal(name) {
this.name = name;
}
Animal.prototype.color = 'white';
var cat1 = new Animal('大毛');
var cat2 = new Animal('二毛');
cat1.color // 'white'
cat2.color // 'white'
复制代码
构造函数Animal
的prototype
属性,就是实例对象cat1
和cat2
的原型对象。原型对象上添加一个color
属性,结果,实例对象都共享了该属性。
所有对象都有自己的原型对象(prototype)。
当实例对象本身没有某个属性或方法的时候,它会到原型对象去寻找该属性或方法。如果直到最顶层的Object.prototype
还是找不到,则返回undefined
。
如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding)。
由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain)。
如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype
,即Object
构造函数的prototype
属性。也就是说,所有对象都继承了Object.prototype
的属性。这就是所有对象都有valueOf
和toString
方法的原因。
Object.prototype的原型是null。原型链的尽头是null。
Object.getPrototypeOf(Object.prototype)
// null
复制代码
本文整理自阮一峰所作JavaScript教程之相关内容。