最近在学习JS原型链的时候,碰到prototype和__proto__属性时总是会很懵逼,看到网上的面试题后就更晕了,于是查找资料比较了这两个属性,写一篇总结防止自己忘记
- 首先看看MDN上关于__proto__的解释
Object.prototype (en-US) 的 proto 属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]] (一个对象或 null)。
但它不应该与构造函数 func 的 prototype 属性相混淆。被构造函数创建的实例对象的 [[Prototype]] 指向 func 的 prototype 属性。
所以我们现在可以确定__proto__是JS对象里面的一个访问器属性,可以通过它访问内部的[[Prototype]]属性,但是这个[[Protototype]]属性和函数中的prototype属性不一样
- prototype属性 ---函数特有的属性
函数是ECMAScript中最有意思的部分之一,这主要是因为函数实际上是对象。每个函数都是Function 类型的实例 ---JS高级第四版
在JS中函数也是一个对象,它的构造函数是Function(),而prototype是JS每一个函数的一个特殊属性,当我们定义好一个函数后,他就有一个属性prototype指向一个原型对象,使用这个构造函数创建一个对象后,这个对象的__proto__属性指向构造函数的原型对象
3.1看一个例子
function Person() {
this.name = 'Tianj0o'
}
const person = new Person()
console.log(person.__proto__ === Person.prototype)//true
通过Person构造函数创造的person实例的__proto__属性指向Person.prototype,那Person.prototype是什么呢?我们上面已经说了,它是一个原型对象,函数定义后就会创建,所以它是一个对象,那它的肯定也有__proto__属性,我们访问一下看看
console.log(Person.prototype.__proto__)
//输出 [Object: null prototype] {}
为什么是这个呢,我们想一下这是一个对象,那它肯定是由一个构造函数创建--Object(), 所以这个对象的__proto__属性应该指向Object.prototype
console.log(Object.prototype) // [Object: null prototype] {}
console.log(Object.prototype === Person.prototype.__proto__)//true
按前面的规律,Object.prototype 也是一个对象,那它应该也有__proto__属性指向一个原型对象,这个对象也有__proto__属性,这个一直递归下去,这样明显不好,所以我们输出一下看看Object.prototype的__proto__会发现这个值是null,那__proto__属性的查找到这里也就结束了。 一般称Object.prototype这个对象为顶级原型对象。
3.2 再来研究一下Person函数作为一个对象它的__proto__属性,参照上面的方法,Person作为一个函数对象,那它的构造函数应该是function Function(),所以它的__proto__属性应该指向Function.prototype,输出一下看看
console.log(Person.__proto__ === Function.prototype)//true
那Person.__proto_._proto_(Function.prototype._proto_)是什么呢?按照上面的方法可以确定是Object()这个函数的原型
console.log(Person.__proto__.__proto__ === Object.prototype)//true
可以发现又找到了顶级原型Object.prototype。
现在我们看这张经典的图应该清晰很多了
感谢阅读😏😏😁
首发于我的博客tianj0o.xyz