prototype、__proto__、constructor,今天,我终于搞清楚了它们之间的关系。
prototype是函数才有的属性。
_proto_是每个对象都有的属性。
首先我们来了解几个概念:构造函数、原型对象、实例。
关于构造函数
构造函数与其他函数的唯一区别,就在于调用它们的方式不同。任何函数,只要通过new
操作符来调用,那它就可以作为构造函数;而任何函数,如果不通过new
操作符来调用,那它跟普通函数也不会有什么两样。
比如说:
var person = new Object();
这行代码创建了Object引用类型的一个新实例。使用的构造函数是Object。
关于原型对象
每个函数都有一个prototype
(原型)属性,这个属性是一个指针,指向该函数的原型对象。因此,构造函数的prototype
(原型)属性指向这个构造函数的原型对象。
所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。这句话的意思就是:Person.prototype.constructor == Person
。
关于实例
当调用构造函数创建一个新实例后,该实例的内部将包含一个指针,指向构造函数的原型对象。ECMA-262第5版中管这个指针叫[[Prototype]]。虽然在脚本中没有标准的方式访问[[Prototype]],但Firefox、Safari和Chrome在每个对象上都支持一个属性__proto__
。
三者之间的关系
function Person(){}
Person.prototype.name = “Nicholas”;
Person.prototype.age = 29;
Person.prototype.job = “Software Engineer”;
Person.prototype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
以上面的代码为例,构造函数即指Person,原型对象即Person.prototype,Person的实例即person1。
下图展示各个对象之间的关系:
总结它们之间的关系如下:
- Person.prototype指向原型对象;
- Person.prototype.constructor指向Person;
- person1.__proto__指向Person.prototype;
- person1.constructor指向Person;
- 指向可以理解为(==)。