Function.prototype
和 Object.prototype
都是 JavaScript 中的重要原型对象,它们分别用于所有函数对象和所有普通对象的原型链。它们有很多不同之处,主要体现在它们所代表的对象类型和功能上。
1. 作用域和对象类型
-
Object.prototype
是所有普通 JavaScript 对象的原型。- 任何通过
object
构造器(如new Object()
)或字面量(如{}
)创建的对象都继承自Object.prototype
。 Object.prototype
上定义了许多通用的属性和方法,比如toString()
、hasOwnProperty()
、valueOf()
等。
- 任何通过
-
Function.prototype
是所有函数对象的原型。- 任何通过
function
关键字声明的函数,或通过new Function()
构造的函数,都会继承自Function.prototype
。 Function.prototype
上定义了与函数相关的方法,如call()
、apply()
、bind()
等。
- 任何通过
2. 原型链的区别
-
Object.prototype
是最顶层的原型:- 所有普通对象(包括数组、日期对象等)最终都继承自
Object.prototype
,并且它位于原型链的最顶端。 Object.prototype
本身没有继承其他对象,它是原型链的“根”。
- 所有普通对象(包括数组、日期对象等)最终都继承自
-
Function.prototype
继承自Object.prototype
:- 所有函数对象都继承自
Function.prototype
,因此,Function.prototype
上的方法可以被所有函数使用。 - 同时,
Function.prototype
也继承了Object.prototype
,这意味着函数也可以访问Object.prototype
上的方法。
- 所有函数对象都继承自
3. 核心属性和方法的区别
-
Object.prototype
的常见属性和方法:toString()
: 返回对象的字符串表示。hasOwnProperty()
: 检查对象是否拥有某个自有属性。valueOf()
: 返回对象的原始值。constructor
: 指向创建该对象的构造函数。
-
Function.prototype
的常见属性和方法:call()
: 用于调用函数,并指定this
上下文和传入的参数。apply()
: 与call()
类似,不过apply()
接受参数是一个数组。bind()
: 创建一个新的函数,绑定指定的this
值和初始参数。constructor
: 指向Function
构造函数。
4. 构造器和实例的关系
-
Object.prototype
是普通对象的构造器原型。所有对象的__proto__
链接最终都会指向Object.prototype
。因此,你可以通过对象访问到Object.prototype
上的方法。- 例如:
const obj = {}; console.log(obj.__proto__ === Object.prototype); // true
- 例如:
-
Function.prototype
是函数对象的构造器原型。所有函数对象的__proto__
链接最终指向Function.prototype
。- 例如:
function foo() {} console.log(foo.__proto__ === Function.prototype); // true
- 例如:
5. 总结
特性 | Object.prototype | Function.prototype |
---|---|---|
作用 | 所有对象的原型 | 所有函数对象的原型 |
继承关系 | 是原型链的最顶层,没有继承其他对象 | 继承自 Object.prototype |
主要方法 | toString() , hasOwnProperty() , valueOf() | call() , apply() , bind() , constructor |
构造器 | 所有普通对象(如 {} )的构造器原型 | 所有函数(如通过 function 关键字声明的)构造器原型 |
例子
// 1. `Object.prototype`
const obj = {};
console.log(obj.hasOwnProperty('toString')); // true
console.log(obj.toString()); // '[object Object]'
console.log(obj.constructor === Object); // true
// 2. `Function.prototype`
function myFunction() {}
console.log(myFunction.call); // function call()
console.log(myFunction instanceof Function); // true
console.log(myFunction.constructor === Function); // true
表达式 Function.prototype == Object.__proto__
的输出结果是 true
。
解析:
-
Function.prototype
:Function.prototype
是所有函数对象的原型,提供了函数相关的方法(如call()
、apply()
、bind()
等)。- 例如,对于
function foo() {}
来说,foo
是一个函数对象,它继承自Function.prototype
。
-
Object.__proto__
:Object.__proto__
代表的是Object
构造函数的原型链,也就是Function.prototype
。这是因为在 JavaScript 中,Object
也是一个函数对象,而所有的函数对象的原型都指向Function.prototype
。- 具体来说,
Object
是通过函数构造的,它的__proto__
属性指向Function.prototype
。
进一步验证:
console.log(Function.prototype === Object.__proto__); // true
在这里:
Function.prototype
是所有函数对象的原型。Object.__proto__
是Object
构造函数的原型链,它指向Function.prototype
。
因此,Function.prototype
和 Object.__proto__
是同一个对象,所以输出 true
。
在 JavaScript 中,Object
是一个构造函数,而所有的 构造函数 都是 函数对象,因此 Object
本身也就是一个函数对象。这个理解涉及到 JavaScript 的原型链和构造函数的概念。具体来说,所有的 函数对象 的原型都指向 Function.prototype
,这意味着 Object
作为一个函数对象,也会继承 Function.prototype
的属性和方法。
1. Object
是一个函数对象
在 JavaScript 中,Object
是一个构造函数,用于创建对象。例如:
let obj = new Object();
console.log(obj); // 输出: {}
Object
本身是一个函数对象(构造函数),它是由 JavaScript 引擎定义并实现的。在 JavaScript 中,函数也是对象,因此 Object
作为函数对象,继承自 Function.prototype
。
2. 函数对象的原型链
JavaScript 中的所有 函数 都是对象,且都继承自 Function.prototype
。这意味着:
Object
是一个函数对象,因此它有一个prototype
属性,该属性指向Function.prototype
。Function.prototype
本身继承自Object.prototype
。
这使得所有函数(包括 Object
、Function
、用户自定义的函数等)都具有 Function.prototype
上的方法,比如 call
、apply
、bind
等方法。
3. 原型链关系
理解这一点需要知道 JavaScript 中的原型链。Object
构造函数本身是一个函数对象,其原型链如下:
Object
是一个函数对象,它的原型是Function.prototype
。Function.prototype
是一个函数对象,它的原型是Object.prototype
。
所以,Object
的原型链如下:
Object --> Function.prototype --> Object.prototype --> null
4. 实例代码
你可以通过 Object.prototype
和 Function.prototype
来查看它们的关系:
console.log(Object.prototype); // 输出: { ... } (Object.prototype 对象)
console.log(Object.__proto__); // 输出: Function.prototype
console.log(Function.prototype); // 输出: { ... } (Function.prototype 对象)
console.log(Function.__proto__); // 输出: Object.prototype
这表明:
Object
是一个构造函数,其原型指向Function.prototype
。Function.prototype
继承自Object.prototype
,因此所有函数对象(包括Object
)都具有Function.prototype
中的方法。
5. Function.prototype
上的方法
因为 Object
是一个函数对象,它继承了 Function.prototype
上的所有方法。举个例子:
console.log(Object.call); // 输出: [Function: call]
console.log(Object.apply); // 输出: [Function: apply]
这些方法(如 call
和 apply
)是 Function.prototype
上的方法,所有函数对象(包括 Object
)都可以调用它们。
6. 总结
Object
是一个函数对象,它是由 JavaScript 引擎实现的构造函数。- 所有函数对象(包括
Object
、Function
、用户定义的函数等)都有一个prototype
属性,指向Function.prototype
。 Function.prototype
上的方法(如call
、apply
、bind
)是所有函数对象所共享的,因此Object
也能继承并使用这些方法。
关键概念:
- 函数对象:在 JavaScript 中,函数本身也是对象,它是由
Function
构造的。 - 原型链:函数对象的原型指向
Function.prototype
,Function.prototype
又指向Object.prototype
,形成一个继承链。
总结
Object.prototype
是所有对象的原型,提供了与对象相关的通用方法。Function.prototype
是所有函数的原型,提供了与函数执行相关的专用方法,同时继承自Object.prototype
,因此函数也能访问对象的一些通用方法。Function.prototype == Object.__proto__
的输出结果是true
,因为Object
构造函数本身是通过Function
构造的,其原型链指向Function.prototype
。