typeof判定为function却无法调用?JavaScript问题求助
为什么
Array.prototype.concat.call赋值后无法调用? 这个问题其实是JavaScript中this绑定机制的经典陷阱,咱们一步步拆解来搞懂:
核心原因:call方法丢失了原本的this指向
首先要明确:Array.prototype.concat是一个函数,而函数的call属性其实是继承自Function.prototype.call——也就是说,Array.prototype.concat.call本质上就是Function.prototype.call这个方法本身。
当你把它赋值给变量x之后,调用x()的时候,这个call方法的this指向就丢失了:
- 原本调用
Array.prototype.concat.call(arr, ...args)时,call方法内部的this指向的是Array.prototype.concat这个函数,所以call会帮我们把concat的this绑定到arr上,然后执行concat。 - 但单独调用
x()或者x([1,2],[3,4])时,在现代浏览器/Node默认的严格模式下,call方法的this会变成undefined;非严格模式下是全局对象window/global。而call方法本身需要它的this是一个可调用的函数,所以自然会抛出TypeError: x is not a function(本质是“undefined/window不是可调用的函数”)。
对应你的补充发现逐一解释
x([1,2],[3,4])无法运行:这里你传入的第一个参数[1,2]会被当作call方法的this,而数组不是函数,call没法把它当作目标函数去执行,所以报错。Object.prototype.toString.call(x)返回[object Function]:完全正确,因为x就是Function.prototype.call,本身确实是一个函数实例,所以toString会正确识别它的类型。Array.prototype.concat.apply也有同样问题:和call同理,apply也是继承自Function.prototype.apply,赋值后同样丢失了原本指向concat的this。- 逗号表达式调用失败:
(0, Array.prototype.concat.call)这种写法会触发“上下文剥离”,把call方法从concat的属性链中拿出来,变成一个独立的函数引用,所以调用时还是丢失了this指向,结果和直接调用x一样。
怎么解决这个问题?
如果你想让x能正常工作,需要把call方法的this固定绑定到Array.prototype.concat上,用bind方法即可:
var x = Array.prototype.concat.call.bind(Array.prototype.concat); x([1,2], [3,4]); // 输出 [1,2,3,4]
或者调用时手动指定call的this:
var x = Array.prototype.concat.call; x.call(Array.prototype.concat, [1,2], [3,4]); // 输出 [1,2,3,4]
内容的提问来源于stack exchange,提问作者Pedro A
相关产品推荐
相关产品推荐

