??摘要
本文主要深入介绍了[[prototype]]
和prototype
这两个属性,顺着这个思路讲解了原型链的形成过程。
从一个很迷惑的经典题目开始。
Object instanceof Function //true
Function instanceof Object //true
首先,我们要了解,这里的Object
和Function
都是指JS中的内置函数对象。为了讲透它,我们从两个属性入手,[[prototype]]
和prototype
。
这两个属性都说是指向原型。那有什么不同呢。
每一个函数在创建之后都会拥有一个名为prototype
的属性,这个属性指向该函数的原型对象。[[prototype]]
是任何对象都有的内部属性。也就是,只有函数对象有prototype
属性,而每个对象都有[[prototype]]
属性。
【这里说明一下,由于[[prototype]]
是内部属性,所以ES5之前是不可以直接访问的,但Safari、Firefox和Chrome都支持一个属性_prpto_
,可以用它来访问。从ES5后,新增了方法Object.getPrototypeOf()
可以用来访问这个内部属性。】
[[prototype]]
指向的创建这个对象的函数(也就是构造函数)的prototype
。
function SuperType () {
}
function SubType () {
}
SubType.prototype = new SuperType(); //subType.prototype === SuperType
var instance = new SubType(); //instance的构造函数是SubType
console.log(Object.getPrototypeOf(instance)); //SuperType{}
我们知道二者的作用都是用来实现基于原型的继承,但prototype
可以用来实现属性的共享,而[[prototype]]
主要是用来构成原型链。所以我们日常所说的原型链其实这个原型指的是[[prptotype]]
的指向构成的链,而不是prototype
。还是上面那个栗子,我们用图来表示一下其原型链和原型关系。
图中,蓝色线表示原型链指向,其中,实线是实例instance
的原型链,虚线其他的[[prototype]]指向。黄色线是原型对象指向。
SubType
来生成一个实例instance
的时候,其内部属性[[prototype]]
指向其构造函数SubType
的原型对象SubType.prototype
。SubType
的原型对象手动更改成了SuperType
的一个实例,所以其构造函数是SuperType
,[[prototype]]
指向SuperType.prototype
。new Object()
得来,所以SuperType.prototype
的[[prototype]]
指向Object.prototype
。Function.prototype
的几条蓝色虚线:内置的一些生成类型对象的函数,例如,Object|Number|Stirng|Array|Function
等,以及用function(){}
的方式创建的函数以及都相当于通过new Function()
得来,所以,其[[prototype]]
指向Function.prototype
。Function.prototype
指向Object.prototype
。这也是JS内置的,这也就是我们常说的函数本身也是对象。你可能会问,那Object.prototype
的[[prototype]]
是什么呢,不是所有对象都有[[prototype]]
么,JS中规定,它的原型是null
。原型链到此为止。
还有一点需要注意的是,JS内在规定,Funtion.prototype
是一个函数。
console.log(typeof Object.prototype); //object
console.log(typeof Function.prototype); //function
到现在,我们距离开头那个问题的答案只剩一步之遥。
instanceof的用法
instanceof运算符用于j检测构造函数的prototype属性是否出现在对象的原型链中的任何位置
这样顺着图中原型链一找,不难得到答案。
原文:https://www.cnblogs.com/dadaxindeyuanzi/p/11516261.html