You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Function.prototype.call赋值给变量时异常:为何一段正常一段抛TypeError?

为什么把Function.prototype.call赋值给变量后调用会抛出TypeError?

这个问题其实戳中了JavaScript中this绑定和方法调用的核心细节,我来给你拆解清楚:

首先先明确你说的两种场景:

正常工作的代码

console.log.call(undefined, 'hello'); // 输出 "hello"

抛出异常的代码

const myCall = Function.prototype.call;
myCall(console.log, 'hello'); // 抛出 TypeError: Function.prototype.call was called on incompatible [object Window](浏览器非严格模式)

核心原因:call方法的执行依赖自身的this指向

Function.prototype.call本身也是一个函数,但它的设计目的是让它的this所指向的函数,以指定的上下文执行。换句话说,call方法内部要求它自己的this必须是一个合法的函数,否则就会报错。

我们来拆解两种场景的this绑定:

  1. 正常场景:当你调用console.log.call(...)时,call方法的this指向的是console.log——这是一个标准的函数,完全符合call的要求。所以call内部会正确执行console.log,传入参数'hello'。
  2. 报错场景:当你把Function.prototype.call赋值给变量myCall后,调用myCall(...)时,this的绑定规则发生了变化:
    • 在非严格模式下,全局作用域中调用普通函数,this默认指向全局对象(浏览器里是window,Node.js里是globalThis)
    • 在严格模式下,this会是undefined

不管哪种情况,这个this都不是一个函数,而call方法内部会检查自身的this是否为函数,不符合要求就会抛出TypeError。

如何让赋值后的call正常工作?

如果非要把call赋值给变量后使用,你需要手动给它绑定正确的this(也就是你要调用的目标函数):

// 方式1:用bind绑定目标函数
const myCall = Function.prototype.call.bind(console.log);
myCall(undefined, 'hello'); // 输出 "hello"

// 方式2:用call的call来绑定this
const myCall = Function.prototype.call;
myCall.call(console.log, undefined, 'hello'); // 输出 "hello"

这两种方式都是强制让myCall(也就是call方法)的this指向console.log,从而满足它的内部要求。

总结

本质上,Function.prototype.call是一个需要依赖自身this才能工作的方法,它不是一个独立的工具函数。直接通过函数实例(比如console.log)调用call时,this会自动绑定到该函数实例;但当你把它单独抽离成变量后,this的绑定丢失,就会触发异常。

内容的提问来源于stack exchange,提问作者Eliran Pe'er

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:05:16