原型和原型链
核心概念
- 每一个对象都有
__proto__
属性,只有函数对象有prototype
属性 - 函数对象的
prototype
属性指向的是它的原型对象,函数对象也拥有__proto__
属性 - 对象的
__proto__
属性指向它的构造函数的原型对象,也就是指向构造函数的prototype
属性 - 原型对象的constructor属性指向其构造函数
以上4点基础概念是我个人认为是理解原型和原型链必不可少的基础,下面我用一个简单的示列来讲解原型和原型链
function Person(){
this.name = 'xxx'
}
var person1 = new Person();
这是我们很常见的通过构造函数创建类的方法,我们来看看究竟发生了什么。
person1.__proto___ === Person.prototype;//true
如核心概念中所描述的,对象(person1)的__proto__
属性指向其构造函数(Person)的prototype
属性。
Person.prototype.constructor === Person;//true
如核心概念中所描述的, 原型对象的(Person.prototype)constructor
属性指向构造函数本身(Person)。
person1.prototype;
Person.prototype;
person1.__proto__;
Person.__proto__;
如核心概念中所描述的,每一个对象(person1,Person)都有__proto__
属性,只有函数对象有prototype
属性
通过上面的示列,我们验证我在开头所说的4个核心概念,下面我们继续刨根问底。
-
Person.__proto__
是什么?
我们先看看Person的定义function Person(){ this.name = 'xxx' }
显然
Person
是由函数构造而成,那么根据我们的核心概念,Person.__proto__
就应该指向它的构造函数的原型对象,而Person
的构造函数是Function
,所以Person.__proto__ === Function.prototype;//true
-
Person.prototype.__proto__
是什么?
Person.prototype
是一个原型对象,原型对象也是对象,那么它必定有__proto
,而对象的__proto__
是指向其构造函数的原型属性指向的原型对象,而一般对象是由Object创建的,所以Person.prototype.__proto__ === Object.prototype;//true
所以,通过上面的两个问题,我们已经将原型属性拓展到了Function构造函数对象和Object构造函数对象,那么我们再来探索一下Function构造函数的原型以及Object构造函数的原型。
我们继续看下面4个对象
-
Function.prototype
-
Function.__proto__
-
Object.__proto__
-
Object.prototype
我们发现Function.prototype
和Function.__proto__
以及Object.__proto__
的输出是一样的,都是ƒ () { [native code] }
但是三者相等么?
Function.__proto__ === Function.prototype;
Object.__proto__ === Function.prototype;
答案是相等!!是不是很神奇。
那么我们继续看看这Function.prototype
是个什么东西.
typeof Function.prototype; //"function"
Function.prototype instanceof Object;//true
Function.prototype instanceof Function;//false
也就是说这个Function.prototype
使用typeof
判断他是一个函数,使用instanceof
看,他是一个对象而不是函数,所以还是有点意思啊!!我们将Function.prototype
看做是Function
构造函数的原型对象F
, 将前面我们还未讨论的Object.prototype
看做是O
此时我们看看F.__proto__
和 O
,你会发现两者的输出是一样的
而且
Function.prototype.__proto__ === Object.prototype; //true
Object.prototype.__proto__ === null;//true
我使用下图来描述前面我们所验证的一些,来帮助大家更深刻的理解
看着这个图是不是有一种万物皆对象,万物皆空的感觉!!!
说了这么多,我们还没有说什么是原型链。其实在上图的基础上,我们去理解原型链就很简单了,下面直接给出定义,大家自己琢磨琢磨。
所谓原型链,就是在查找对象的属性和方法时,先在对象自身的属性和方法上查找,如果找到了就结束查找,如果没有就会沿着对象的__proto__
属性指向的对象向上级查找,在上级对象中也是同样的道理进行查找,直到null
也就是Object.prototype.__proto__
结束。
以上是我个人总结的原型和原型链相关的知识,欢迎小伙伴们一起在评论区讨论学习!!!