为什么JavaScript构造函数默认原型是Object.prototype而非Function.prototype?
JS原型链规则答疑
你出现预期偏差的核心原因是混淆了两类完全独立的原型链逻辑:构造函数自身作为函数对象的原型链,和构造函数的prototype属性(供实例继承的原型对象)的原型链。
第3、4点结果解释
- 所有函数的
prototype属性默认是一个普通对象,不是函数:Thing.prototype本身只是个带constructor属性指向Thing的普通对象,和手动定义的{}没有本质区别 - 普通对象的
__proto__自然指向Object.prototype,和Function.prototype无关 - 所以
table.__proto__是Thing.prototype,Thing.prototype.__proto__是Object.prototype,自然第3点结果为true,第4点结果为false
A、B点结果解释
- 所有函数(包括JS内置的
Function、Object构造函数本身)都是Function的实例,所以函数的__proto__都指向Function.prototypeFunction作为构造函数,自身也是函数,所以Function.__proto__ === Function.prototypeObject作为构造函数,自身也是函数,所以Object.__proto__ === Function.prototype- 所以B点的
Function.__proto__ == Object.__proto__自然为true
- A点的等式之所以不成立,是因为
Function.prototype的__proto__才指向Object.prototype,而非Function.__proto__直接指向Object.prototype,完整原型链是Function -> Function.prototype -> Object.prototype -> null
相关设计的逻辑
这是ECMAScript标准明确规定的原型链规则,核心是把两类继承场景分开:
- 普通实例的继承走
实例.__proto__ -> 构造函数.prototype这条线,构造函数的prototype是什么类型、继承自谁,完全可以自定义,不受构造函数自身类型的限制 - 函数对象的通用能力(比如
call、apply、bind)都挂载在Function.prototype上,所有函数都通过自己的__proto__继承这些能力,和它的prototype属性无关
内容的提问来源于stack exchange,提问作者Muhammad Shoaib
相关产品推荐
相关产品推荐

