在说原型链之前,我们需要先来讲讲构造函数
1、构造函数
当任意一个普通函数用于创建一类对象时,它就被称作构造函数。
function Person(name, age) {
this.name = name;
this.age = age
}
var person1 = new Person('marco', '18');
上面的例子中 person1 是 Person 的实例。这个实例有一个 constructor (构造函数)属性,该属性(是一个指针)指向 Person。 即:
console.log(person1.constructor == Person); // true
由此我们可以得出:
实例的构造函数属性(constructor)指向构造函数。
2、原型对象
每个函数对象都有一个 prototype 属性,即:函数对象.prototype就是原型对象。
函数对象是指通过new Function()来创建的对象和通
过function关键字来创建一个对象。
我们通过console.dir()打印上面例子中 构造函数Person 和实例person1 的属性来看看,如下图所示:
因此我们可以得出另外一条规律:
每个对象都有__proto__ 属性,但是只有函数对象才有 prototype 属性
1、我们还是以Person为例继续讲解,我们将原型对象Person.prototype展开来看看里面有些什么,如下图:
可以发现原型对象Person.prototype里有constructor属性,该属性里的内容和函数Person里的内容一致,因此我们大胆的猜测一下:Person.prototype.constructor 是否与 Person 相等
console.log(Person.prototype.constructor == Person) // true
所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person)。即:Person.prototype.constructor == Person
根据我们最开始得出的结论,实例的构造函数属性(constructor)指向构造函数 :person1.constructor == Person 与上面的出的结论相结合即可得出:原型对象的构造函数(constructor)== 实例的构造函数(constructor)
Person.prototype.constructor == person1.constructor
3__proto__
我们知道 每个对象都有__proto__ 属性,实际上它指向了创建它的构造函数的原型对象。
即:person1有一个__proto__属性,它指向了构造函数Person的原型对象Person.prototype
验证一下看看两者是否相等
console.log(person1.__proto__ == Person.prototype); //true
所以可以得出:
person1.__proto__ == Person.prototype
4、原型链
JavaScript中的所有对象都来自Object;所有对象从Object.prototype继承方法和属性
由上图可以看出 实例person1的__proto__的__proto__ 和 原型对象Person.prototype的__proto__都指向了Object
综合可以得出:
person1.__proto__.__proto__ == Object.prototype;
Person.protype.__proto == Object.prototype
那Object.prototype的__proto__又指向了哪里呢?
Object.prototype.__proto__ == null // true
指向了null,表示已经到顶了。
原型链结论如下:
person1.constructor == Person;
person1.__proto__ == Person.prototype;
Person.prototype.constructor == Person;
Person.prototype__proto__ == Object.prototype;
Object.prototype.__proto__ == null;