可选链接 - Function.prototype.apply 在未定义时调用,这是未定义而不是函数
Posted
技术标签:
【中文标题】可选链接 - Function.prototype.apply 在未定义时调用,这是未定义而不是函数【英文标题】:Optional Chaining - Function.prototype.apply was called on undefined, which is an undefined and not a function 【发布时间】:2021-06-11 01:07:39 【问题描述】:Using optional chaining with function calls causes the expression to automatically return undefined instead of throwing an exception if the method isn't found.
注意:代码使用的是spread syntax
,而不是rest parameters
。
const fn1 = undefined
const args = []
const fn2 = () =>
const fn3 = () =>
console.log(fn1?.(...args, fn2, fn3))
错误:
console.log(fn1?.(...args, fn2, fn3))
^
TypeError: Function.prototype.apply was called on undefined, which is an undefined and not a function
【问题讨论】:
只有当...args
出现在函数调用末尾以外的任何其他位置时,才会出现问题。很奇怪。
我们收到这个错误很奇怪。通常,您会收到“fn1 不是函数”错误。即使不使用可选链接,也会出现此错误。比较:(() => (test: undefined).test(...([])) )() // Uncaught TypeError: (intermediate value).test is not a function
与 (() => (test: undefined).test(...([]), 1) )() // Uncaught TypeError: Function.prototype.apply was called on undefined, which is a undefined and not a function
看起来像是 chromium 浏览器的问题,在 Mozilla Firefox 中运行良好
这绝对是一个错误——他们对可选链的实验性实现不适用于他们使用扩展语法转换调用的方式。
【参考方案1】:
原来是 V8 的 bug,我已经提交了there,希望能尽快修复。
更新:it has been fixed。
【讨论】:
【参考方案2】:...rest 参数需要遵循一些规则。
其中一个规则是 ...rest 参数只能是最后一个参数。
foo(...one, ...wrong, ...wrong)
foo(...wrong, bad, bad)
foo(ok, ok, ...correct)
见:
https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Functions/rest_parameters
【讨论】:
但问题是使用传播,而不是休息。传播参数可以出现在任何地方,任何次数以上是关于可选链接 - Function.prototype.apply 在未定义时调用,这是未定义而不是函数的主要内容,如果未能解决你的问题,请参考以下文章
javascript中Function.prototype的问题
《javascript设计模式与开放实践》学习Function.prototype.bind