关于js中的原型链的理解
我们知道无论什么时候只要创建了一个函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象,默认情况下所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含了一个指向prototype属性所在函数的指针。当调用构造函数创建一个新实例后,该实例内部就会包含一个[[prototype]]指针(内部属性),指向构造函数的原型对象。例如以下的代码:
function Person(){ } Person.prototype.name = "pan"; Person.prototype.age = 23; }; var person1 = new Person();
这段代码中Person构造函数、Person的原型属性以及Person的现有实例person之间的关系可以用下图来表示:
在这里,Person.prototype指向了原型对象,而Person.prototype.constructor又回指了Person。实例person1包含了一个指向Person.prototype的内部属性[[Prototype]]。
现在来看看我们上面的图是否说对了呢?
function Person(){ } Person.prototype.name = "pan"; Person.prototype.age = 23; var person1 = new Person(); console.log(Person.prototype); console.log(person1.__proto__); console.log(Person.prototype.constructor); console.log(person1.__proto__.constructor); console.log(person1.name);
我们可以看到Person.prototype与person1.__proto__都是同一个对象Person{},所以Person.prototype.constructor和person1.__proto__.constructor都是Person这个函数。又因为person1可以利用原型链向上查找到Person.prototype的属性并使用,所以person1.name的值为pan。
原型链
prototype是函数的一个内置属性,这个属性是一个指针,指向原型对象;
_proto_([[prototype]])是对象的内置属性,而函数也是一个对象,所以就会形成一条_proto_连起来的链条,形成原型链,递归访问_proto_的尽头是null
举个栗子:
var A = function(){} var a = new A();
会有如下的原型链关系
a的_proto_指向A.prototype(A的原型对象),A.prototype的_proto_指向Object.prototype(Object的原型对象),Object.prototype的_proto_最终指向的是null
下面是一张更详细的原型链图(来自网上)