原型链简单讲解
函数为红色,对象为蓝
a为函数 proto表示原型,a可以通过prototype来访问
在控制台输入
function a(){}
a.prototype // {}
const b = ()=>{}
b.prototype // undefined 箭头函数没有prototype
然后我们可以通过new a()
来创建一个a的实例 暂时称ins
我们通过ins这个实例利用ins.__proto__
可以找到创建ins的构造函数的原型 (隐式原型)
function a(){}
const ins = new a()
a.prototype // {}
ins.__proto__ === a.prototype // 结果为true
这样就产生了一个基本的原型结构图
我们都知道在js中创建对象是通过new () 来创建的,所以就产生下面的关系
对象obj是一个函数new的实例,所以obj的隐式原型就等于函数的prototype
如下
var obj = {}
obj.__proto__ === Object.protptype // true
所以Object也是一个函数创建出来的,一个函数有自己的三角关系,所以Object也有自己的三角关系
根据箭头颜色来判断会容易理解哦
特殊:Object是特殊的,Object的原型对象指向了null
所以原型链就出来了
从一个对象开始,依次找到它的隐式原型,再找到隐式原型的隐式原型,最后找到null为止
我们要知道,函数是一个特殊的对象,它是可以被new出来的,如何验证函数是对象呢?
如下,我们创建一个相加函数,我们既可以传参来得到,也可以利用sum.a
来赋值
function sum (a,b) {return a+b}
sum(1,2) // 3
sum.a = 2
sum.a //2
所以函数是被谁new出来的呢?是Funciton
,所以上面函数还可以这样写
const sum2 = new Funciton("a","b","return a+b")
sum2(1,2) //3
Function.prototype // {}
所以我们结构图就可以多级嵌套,要根据箭头来理解
这样我们就可以解释为什么函数都有bind
、call
方法
function sum (a,b) {return a+b}
sum.bind
sum.call
函数自身没有bind
方法,所以就会通过原型链去找,如何找呢?
sum函数通过黑色箭头,找到了Function
的prototype
,然后看Function
有没有bind
呢?发现有
Function.prototype.bind
就像函数为什么都有toString
方法呢?
sum
通过原型链,找到Function
的prototype
,发现没有,继续通过原型链找到Object
的prototype
,发现是有toString
的
function sum (a,b) {return a+b}
sum.toString
Object.prototype.toString
最后,既然都有隐式原型,那Function
的隐式原型指向谁呢?就是黑色箭头指向谁呢,其实Function的隐式原型指向Function的原型
Function.__proto__ === Function.prototype
这样我们就简单理解了原型链,只要好好理解各个箭头的关系等,就可以画出原型链的图