javascript - Javascript:typeof 表示“函数”,但不能作为函数调用
问题描述
这次我真的对 Javascript 感到困惑:
var x = Array.prototype.concat.call;
typeof x; // function
x(); // Uncaught TypeError: x is not a function
这到底是怎么回事?
如果有帮助,我还注意到:
x([1,2],[3,4])
也不起作用toString
也认为这是一个功能:Object.prototype.toString.call(x); // "[object Function]"
这也发生在
Array.prototype.concat.apply
.当它被强制作为表达式时,它也不起作用:
(0, Array.prototype.concat.call)([1,2],[3,4]); // Same TypeError
在 Chrome 和 Node.js 中测试。
解决方案
该错误具有误导性。x是一个函数,但是它丢失了引用的函数(concat),这会引发错误
在 firefox 上运行会给出更具描述性的错误
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Called_on_incompatible_type
它的意思是该call
函数没有任何约束。就像你拿一个像这样的对象一样:
const a = {
b: 2,
test() {
console.log('hi', this.b);
}
};
const c = a.test;
c();
hi undefined
当你失去了函数与 b 的关系时,你会得到。
您可以通过执行c.bind(a)()
或c.call(a)
该call
函数的行为类似。每个函数都是一样的,伪代码看起来像这样:
class Function {
constructor(functionDefinition) {
this.functionDefinition = functionDefinition;
}
call(newThis, ...args) {
// take this.functionDefinition, and call it with `this` and `args`
}
}
由于您要提取调用函数,因此它会丢失与之关联的函数对象。
您可以通过将 concat 绑定到函数或使用 call on call 来解决此问题 :-)
const a = []
const boundFn = a.concat.call.bind(a.concat)
console.log(boundFn([3], [1,2]));
// Or, you can use `call` to pass in the concat function
const callFn = a.concat.call;
console.log(callFn.call(a.concat, [4], [1,2]))
推荐阅读
- javascript - 在方法内将图像 onload 添加到画布不起作用
- java - 如何在 RecylerView 中保存“PDF”文件?
- postgresql - TypeORM:在运行时为 EntityManager(或存储库)动态设置数据库模式?
- c# - 将带有特殊字符的字符串转换为十六进制 - C#
- awk - How can I use sed to generate an awk file?
- python - 如何获取列表框中项目的索引
- debugging - Custom response header columns in Firefox's Network Monitor
- spring - 如何让这个 spring-boot 代码在 weblogic 10.3.6 上工作?
- css - CSS网格 - 不同屏幕+背景上的可变布局位置
- javascript - 如何打开从 pwa(在 android shell 中)到另一个浏览器的链接