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

JavaScript中x.call被判定为function却无法执行的原因

为什么x.call看起来是函数却无法执行?

这个问题确实有点反直觉,我来一步步拆解背后的原因:

首先先看你给出的核心代码:

const x = Object.create(function() {});
console.log(x.call) // ƒ call() { [native code] }
console.log(typeof x.call) // "function"
console.log(x.call instanceof Function) // true
x.call() // Uncaught TypeError: x.call is not a function

1. 先搞清楚x.call的来源

你说的没错,x.call是从原型链继承来的——Object.create(function() {})创建的对象x,它的原型([[Prototype]])是那个匿名函数,而函数的原型又指向Function.prototype,所以x会继承Function.prototype.call这个方法。这也是为什么typeof x.call返回function,instanceof Function也返回true。

2. 问题出在call方法的执行逻辑上

Function.prototype.call这个方法的设计初衷,是让函数对象来调用的。当一个函数fn执行fn.call(context)时,call方法内部的this指向的是fn本身——也就是一个合法的函数对象。

但当你执行x.call()时,情况就变了:此时call方法内部的this指向的是x,而x是什么?它只是一个普通对象(虽然原型是函数,但它本身不是函数类型)。

我们可以把call的内部逻辑简化成这样来理解:

Function.prototype.call = function(context, ...args) {
  // 第一步就会检查调用者(也就是this)是不是函数
  if (typeof this !== 'function') {
    throw new TypeError('this is not a function');
  }
  // 后续才是绑定上下文、执行函数的逻辑
};

所以当x.call()执行时,call内部检测到this(也就是x)的类型是object,不是function,直接就抛出了你看到的错误。

3. 验证一下:手动绑定this就能正常执行

如果我们把call方法的this手动绑定到一个函数上,它就能正常工作了:

// 把call的this绑定到一个匿名函数上
x.call.call(function() { console.log("我能执行啦!") });
// 输出:我能执行啦!

这里的原理是:第一个call是x继承来的Function.prototype.call,而call本身也是个函数,所以它也继承了Function.prototype.call(第二个call),通过第二个call把this绑定到真正的函数上,就满足了call方法的执行条件。

4. 关于const x = Object.create(Array)的变体

道理是完全一样的:x的原型是Array构造函数,继承了call方法,但x本身是普通对象,不是函数,调用x.call()时this指向x,不符合call方法的要求,所以同样报错。

总结一下:不是x.call本身不是函数,而是你调用它的方式导致它内部的this指向了非函数对象,触发了call方法内部的类型检查。

内容的提问来源于stack exchange,提问作者Sasha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:57:24