函数对象兼具prototype和__proto__:prototype供其实例继承,__proto__指向function.prototype;其完整原型链为foo→function.prototype→object.prototype→null。

函数对象确实是原型链中不可忽视的一环,不是“例外”,而是关键节点。理解这一点,核心在于认清:函数既是可执行的代码单元,又是普通对象——它既拥有 prototype(作为构造器时供实例继承),又拥有 __proto__(作为对象时自身需要继承)。
函数对象同时具备 prototype 和 __proto__
所有非箭头函数在创建时,JavaScript 引擎会自动为其添加两个属性:
-
prototype:一个对象,供该函数作为构造函数使用时,被 new 出来的实例所共享(即实例的
__proto__指向它); -
__proto__:指向它的构造函数的 prototype —— 而所有函数都是由
Function构造出来的,所以函数对象的__proto__指向Function.prototype。
例如:
function Foo() {}
console.log(Foo.prototype); // { constructor: Foo }
console.log(Foo.__proto__); // Function.prototype
console.log(Foo.__proto__ === Function.prototype); // true
函数的原型链结构是完整的三层链
一个普通函数(如 Foo)的完整原型链是:
-
Foo→Foo.__proto__即Function.prototype; -
Function.prototype→ 它的__proto__是Object.prototype(因为Function.prototype是个普通对象,由Object构造); -
Object.prototype→__proto__为null,链终止。
所以:Foo → Function.prototype → Object.prototype → null。这和数组、字符串等内建类型一样,构成标准的原型链路径。
内建函数(如 Object、Array)也遵循同一规则
它们看起来“天生就有”,但本质上仍是 Function 的实例:
-
Object.__proto__ === Function.prototype; -
Array.__proto__ === Function.prototype; -
Function.__proto__ === Function.prototype(自指,因 Function 是自己的构造器)。
而它们各自的 prototype(如 Object.prototype、Array.prototype)才是普通对象或数组实例真正继承的起点。
为什么这点容易被忽略?
因为日常开发中,我们更常关注「实例对象如何通过原型链找方法」,比如 arr.push() 是怎么找到的。但函数本身也是链上一员,它的行为决定了:
- 谁可以当构造函数(必须有
prototype); - 函数能调用哪些方法(如
bind、call来自Function.prototype); - 为何
typeof Function === 'function'却Function instanceof Object === true(因为它沿__proto__链最终落到Object.prototype)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











