一、基本概念
要想搞明白原型链,需要知道以下概念:
- prototype:
是构造函数中的一个属性,通过这个属性可以访问的该构造函数的原型对象; - constructor构造器:
原型对象中都有constructor构造器,通过这个构造器可以访问到原型对象所对应的构造函数; - 构造函数:
可以通过new关键字调用的函数就是构造函数;构造函数可以用户自行创建,也可以使用js内置的构造函数; - 实例对象:
通过new关键字和构造函数实例化(具体化)后的对象; - __ proto __:
是对象(不仅是实例对象,也可以是函数)中的一个属性,通过这个属性可以访问到创建该对象的构造函数的原型对象
注意
prototype和__ proto __指向的都是原型对象,而constructor指向的是构造函数。
二、原型链
原型链分为对象链和函数链,而通过上面的基本概念,大家应该对原型链有了大概的了解,下面就来详细的解释一下,是怎么形成的“链”。
1.对象链
我们通过一个例子来直观感受一下什么是对象链,代码如下:
function Person(name) {
this.name = name;
}
var person = new Person('yun');
Person.prototype.age = 21;
console.log(person);//{name: 'yun'}
//通过原型链去找age,找到就返回,没有就undefined
console.log(person.age);//21
/*实例对象person的__proto__和构造函数Person的prototype都指向构造函
数Person的原型对象*/
console.log(person.__proto__ === Person.prototype);//true
/* Person原型对象的__proto__指向Person原型对象的构造函数的原型对象,
而所有构造函数(除Object函数本身)的原型对象都是由Object函数的原型对象
构造出来的 */
console.log(Person.prototype.__proto__ === Object.prototype);//true
//简单替换后
console.log(person.__proto__.__proto__ === Object.prototype);//true
//Object函数的原型对象是由null构造出来的
console.log(Object.prototype.__proto__ === null);//true
//简单替换后
console.log(person.__proto__.__proto__.__proto__ === null);//true
图解如下:
对象链就是实例对象根据__ proto __去上级原型对象查找对应属性,找到就返回值,没有找到就返回undefined,而图片中的Function函数的原型对象就和函数链有关
2.函数链
函数链和对象链很相似,对象链明白之后,函数链也就没有什么问题了;还是通过上面的例子来进一步了解函数链,代码如下:
function Person(name) {
this.name = name;
}
var person = new Person('yun');
Person.prototype.age = 21;
//所有函数都是由Function函数的原型对象构造出来的,包括Function本身
console.log(Person.__proto__ === Function.prototype);//true
console.log(Object.__proto__ === Function.prototype);//true
//Function函数自己构造自己
console.log(Function.__proto__ === Function.prototype);//true
/* 由对象链知道所有构造函数(除Object函数本身)的原型对象都是由Object函数
的原型对象构造出来的当然Function函数的原型对象也不例外 */
console.log(Function.prototype.__proto__ === Object.prototype);//true
//简单的替换后
console.log(Function.__proto__.__proto__ === Object.prototype);//true
console.log(Person.__proto__.__proto__ === Object.prototype);//true
console.log(Object.__proto__.__proto__ === Object.prototype);//true
// 在对象链中已经了解到Object函数的原型对象是由null构造出来的
console.log(Object.prototype.__proto__ === null);//true
//简单的替换后
console.log(Function.__proto__.__proto__.__proto__ === null);//true
console.log(Person.__proto__.__proto__.__proto__ === null);//true
console.log(Object.__proto__.__proto__.__proto__ === null);//true
图解如下:
和对象链相比,函数链就是根据构造函数__ proto __向上寻找形成的链
总结
- 将对象链和函数链相结合就是原型链,如下图:
- 对象的__ proto __指向的是创建该对象的函数的原型对象;(谁创建了对象,就去找谁的原型对象)
- 所有除Object函数本身以外的原型对象都是由Object函数的原型对象构造出来的;而Object函数的原型对象的__ proto __则指向null;
- 所有函数都是由Function函数构造出来的,它自身也不例外;
- 函数也是一个对象;
- 所有对象查询三层__ proto __后指向的都是null;
以上就是我对原型链的一些理解,如果有什么不对的地方,欢迎各位大佬在评论区指出呀( •̀ ω •́ )✧