转自:http://blog.csdn.net/wxw_317/article/details/49617767
在 JavaScript 中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript 的对象中都包含了一个 prototype
内部属性,这个属性所对应的就是该对象的原型。
prototype
作为对象的内部属性,是不能被直接访问的。所以为了方便查看一个对象的原型,Firefox 和 Chrome 中提供了 __proto__
这个非标准(不是所有浏览器都支持)的访问器:
function Person(name, age) {
this.name = name;
this.age = age;
this.getInfo = function(){
console.log(this.name + " is " + this.age + " years old");
};
}
var will = new Person("Will", 28);
// 测试:
will.name; // "Will"
will.age; // 28
will.getInfo(); // Will is 28 years old
在上面的代码中,通过了 Person 这个 构造函数 创建了一个 will 对象。下面就通过 will 这个对象一步步展开了解原型。
查看对象 will 的原型
will.__proto__
// 结果:
Object {}
constructor:Person(name, age)
__proto__:Object
person {}
对象就是对象 will 的原型,通过 Chrome 展开可以看到,person {}
作为一个原型对象,也有 __proto__
属性(对应原型的原型)。
will.constructor
// 结果
function Person(name, age){
this.name = name;
this.age = age;
this.getInfo = function(){
console.log(this.name + " is " + this.age + " years old");
};
}
在 JavaScript 的原型对象中,还包含一个 constructor
属性,这个属性对应创建所有指向该原型的实例的构造函数。
在这里,will 对象本身并没有 constructor
这个属性,但是通过原型链查找,找到了 will 原型(will.__proto__
)的 constructor
属性,并得到了 Person 函数。
查看对象 will 的原型(will.__proto__)的原型
will.__proto__ === Person.prototype; // true
Person.prototype.constructor === Person; // true
在 JavaScript 中,每个函数都有一个 prototype
属性,当一个函数被用作构造函数来创建实例时,该函数的 prototype
属性值将被作为原型赋值给所有对象实例(也就是设置实例的 __proto__
属性)。也就是说,所有实例的原型引用的是函数的 prototype 属性。
这里我们用 Person 函数作为构造函数创建了实例 will,will 的原型(will.__proto__
)指向函数 Person 的 prototype
属性(Person.prototype
),所以结果为 true
。
注意: prototype
属性是函数对象特有的,如果不是函数对象,将不会有这样一个属性。
// 对象本身是不具有 prototype 属性的
will.Prototype
// 结果
undefined
当通过 Person.prototype.__proto__
语句获取 will 对象原型的原型时候,将得到 Object {}
对象,后面将会看到所有对象的原型都将追溯到 Object {}
对象。
对于原型对象 Person.prototype
的 constructor
,根据前面的介绍,将对应 Person 函数本身。
通过上面可以看到,Person.prototype
对象和 Person
函数对象通过 constructor
和 prototype
属性实现了相互引用。