当我们说到原型链的时候,我们说的是什么?我个人愚蠢的观点就是在说该对象的构造函数,所以只要你理解了这个对象的构造函数是什么,基本上就理清了 __proto__
跟 prototype
的关系。
先上结论:对象的proto属性,指向该对象的构造函数的原型对象,也就是说,对象的__proto__
等于对象构造函数的prototype
。
公司新来的实习生在学原型链,看了两天多的prototype
跟__proto__
的关系,愣是没看明白。我先是给他找了一篇掘金上比较经典的文章:https://juejin.im/post/6844903605242167303 ,可是还是看的囫囵吞枣,我决定通过我不那么标准的学习方法,整理了一些知识点教会他,并做一次记录吧!(建议搭配掘金的那篇文章一起看!)
function Person(name) {
this.name = name
}
mary = new Person('mary')
mary的构造函数是Person,所以mary.__proto__ === Person.prototype
Person的构造函数是Function
所以Person.__proto__ === Function.prototype
Function本身就是Function的构造函数
所以Function.__proto__ === Function.prototype
到了这里,先记住万物皆对象
的这句话,也就是帮助你去理解下面这个规则(后面我们会继续解释为什么万物皆对象)
Function.prototype.__proto__ === Object.prototype
最后就是万物皆空
Object.prototype.__proto__ === null
回过头来,我们再了解一下什么叫构造函数
在JavaScript中,用 new
关键字来调用的函数,称为构造函数
。
构造函数本身就是一个函数,函数的 __proto__
就是 Function.prototype
,相信这个不需要继续解释。同理我们可以推断出:
Array.__proto__ === Function.prototype
Date.__proto__ === Function.prototype
String.__proto__ === Function.prototype
Number.__proto__ === Function.prototype
Object.__proto__ === Function.prototype
......
现在我们来解释下为什么万物皆对象
,这里期望对instanceof
有了解
instanceof的左值一般是一个对象,右值一般是一个构造函数,用来判断左值是否是右值的实例。instanceof操作符的内部实现机制和隐式原型、显式原型有直接的关系,它的内部实现原理是这样的:
//设 L instanceof R
//通过判断
L.__proto__.__proto__ ..... === R.prototype ?
//最终返回true or false
也就是沿着L的proto一直寻找到原型链末端,直到等于R.prototype为止。知道了这个也就知道为什么以下这些奇怪的表达式为什么会得到相应的值了。
Function instanceof Function //true
Function instanceof Object // true
Object instanceof Function // true
Object instanceof Object // true
Number instanceof Number //false
Number instanceof Function //true
Number instanceof Object //true
所以我们通过new 出来的任何东西,包括数字,字符串,数组,函数,这些对象的proto指向,都会指向Object.prototype上。
不建议单独看这篇文章,写得比较简陋,建议还是先看掘金的那篇,如果需要一些总结,可以看这篇。前端菜狗不配为人师。如有错误欢迎指出