前言
本文主要记录原型、原型链的相关知识。纸上得来终觉浅,要知此事须躬行。来,请随我一起看下去(ง •_•)ง!
关于
鉴于__proto__
被大家所熟知,所以本文还将以__proto__
来写。当然也可用以下函数替换
探寻原型链
function test() {}
test.prototype.myname = function () {
console.log('myname');
}
let a = new test()
console.log(a.__proto__ === test.prototype); // true
a.myname(); // myname
结论一
a
是一个对象,test
的原型在a.__proto__
上a.myname()
其实挂载在a.__proto__
上,省略了__proto__
(隐式属性)a.__proto__.constructor
其实指向的就是test
函数
继续探索
结论二
a.__proto__
类似于第一层,指向(test.prototype
)a.__proto__.__proto__
类似于第二层指向(Object.prototype
)a.__proto__.__proto__.__proto__
类似于第三层指向null
通过以上所看到的结果可以简单的得出一些线索
a.__proto__ === test.prototype
a.__proto__.__proto__ === Object.prototype
a.__proto__.__proto__.__proto__ === null
a.__proto__.constructor = test
a.__proto__.__proto__.constructor === Object
// 同理
test.prototype.constructor === test
Object.prototype.constructor === Object
// 这个特例报错,null没有构造函数
a.__proto__.__proto__.__proto__.constructor // Uncaught TypeError: Cannot read properties of null (reading 'constructor')
有没有被搞乱?来,一张图整理一下思路
看完是不是会更清晰一点?来,继续探究
1. test.__proto__
2. test.__proto__.constructor
3. test.__proto__ === Function.prototype
4. test.__proto__.__proto__
5. test.__proto__.__proto__.constructor
6. test.__proto__.__proto__ === Object.prototype
7. test.__proto__.__proto__.__proto__
运行这些代码
可以看出通过
test
存在一条回环链路!看到这里先别急着往下翻,脑补一下链路
1分37秒思考完了吗?来!小二上图!(ง •_•)ง
看这张图已经比较完善的展示了原型链,但是还有一些分支我们需要补充。继续
// 经典的鸡蛋问题
Function.__proto__ === Function.prototype
// Object既然是函数那new一个试试?
new Object()
// Object函数是否也像test函数一样有__proto__ ?
Object.__proto__
运行这些代码
根据上图代码继续补充
至此我们完成了原型链的图解。
总结
问题
Function.prototype.__proto__
和text.prototype.__proto__
是单向箭头,指向Object.prototype
a.__proto__
也是单向箭头,指向text.prototype
可以得出一些结论null
是原型链的终点Object.prototype
是所有原型方法的起点- 构造函数都是都是
Function的实例
- 对象都是
Object的实例
除了Object.prototype
(因为其__proto__指向null)
来一张有趣的图
著名的鸡蛋蛋鸡,到底先有蛋还是先有鸡呢( ఠൠఠ )ノ?
最后
原创不易大家多多支持,如有疑问的欢迎拍砖!~ o( ̄▽ ̄)o
相关文章推荐