设置Function.__proto__.__proto__为null后出现的原型链异常问题
先拆解几个关键逻辑,再解释你遇到的问题:
1. __proto__是继承来的访问器属性
__proto__并不是对象的自有属性,它是Object.prototype上定义的getter/setter,作用是读写对象的内部[[Prototype]]槽。如果一个对象的原型链里没有Object.prototype,它就无法访问这个__proto__访问器,此时读取obj.__proto__会返回undefined。
2. Function的原型链特殊性
在JavaScript里,Function作为函数构造器有个特殊设计:它的内部[[Prototype]]就是Function.prototype(简单说就是函数构造器的原型指向自身的原型对象)。
当你执行Function.__proto__.__proto__ = null时,实际做了两步:
- 通过
Function.__proto__获取到Function.prototype - 把
Function.prototype的内部[[Prototype]]设为null
这直接切断了Function.prototype与Object.prototype的继承关系,此时Function的原型链变成:Function → Function.prototype → null,不再包含Object.prototype。
3. 为什么Function.__proto__会变成undefined?
因为Function的原型链里没有Object.prototype了,它找不到__proto__这个访问器属性,所以读取Function.__proto__时返回undefined——但这只是访问器不可用了,对象内部的[[Prototype]]槽并没有消失。
4. 控制台的[[Prototype]]为什么还能看到?
浏览器控制台是直接读取对象的内部[[Prototype]]槽来展示的,不受__proto__访问器的影响。所以即使访问器无法使用,控制台依然能显示真实的[[Prototype]],而Function的[[Prototype]]本来就是Function.prototype,所以你会看到它和prototype属性值一致。
代码复现
Function.__proto__.__proto__ = null; console.dir(Function.__proto__) // undefined,因为找不到__proto__访问器 console.dir(Function) // 控制台直接读取内部[[Prototype]],显示为Function.prototype
内容的提问来源于stack exchange,提问作者gogole

