前言
本文主要记录原型、原型链的相关知识。纸上得来终觉浅,要知此事须躬行。来,请随我一起看下去(ง •_•)ง!
关于
鉴于__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.prototypea.__proto__也是单向箭头,指向text.prototype可以得出一些结论null是原型链的终点Object.prototype是所有原型方法的起点- 构造函数都是都是
Function的实例- 对象都是
Object的实例除了Object.prototype(因为其__proto__指向null)
来一张有趣的图
著名的鸡蛋蛋鸡,到底先有蛋还是先有鸡呢( ఠൠఠ )ノ?
最后
原创不易大家多多支持,如有疑问的欢迎拍砖!~ o( ̄▽ ̄)o
相关文章推荐