我有一个字符串,“测试”
。这是一条非常丑陋的字符串,所以让我们 trim 它。
"test ".trim()
返回"test"
。不错!
现在让我们尝试使用该字符串作为参数来完成此操作。
String.prototype.trim.call("test ")
也返回 "test"
。又好啦!
哦,这意味着我可以使用 String.prototype.trim.call
通过 trim 后的对应字符串来映射丑陋的字符串数组,对吗?
["test"].map(String.prototype.trim.call)
不返回["test"]
。
它抛出TypeError:未定义不是一个函数
。
为什么不允许这样做?
最佳答案
所有功能call
方法是相同的函数值:
> String.prototype.trim.call === Function.prototype.call
true
> String.prototype.trim.call === alert.call
true
要调用的函数被传递给Function.prototype.call
作为其 this
值(value)。 this
函数调用的值 varies depending on how the call is made :
f(); // calls f with this === undefined
x.f(); // calls x.f with this === x
x['f'](); // same as previous
f.call(y); // calls f with this === y
f.apply(y, []); // same as previous
在所有未调用的情况下引用函数时,不存在 this
涉及的值(value)。
const f = x.f; // no association with x is maintained
x(); // calls f with this === undefined
所以,当你通过String.prototype.trim.call
时至Array#map
,您正在传递函数 Function.prototype.call
,与 String.prototype.trim
没有关系。 Array#map
然后用 thisArg
调用它given as the second argument ( undefined
,因为您只传递了一个参数)。 Function.prototype.call
调用this
它被赋予的值,正如它所做的那样,并且失败,因为它无法调用 undefined
.
可以通过传递正确的 this
值来修复代码如thisArg
:
[" test "].map(String.prototype.trim.call, String.prototype.trim)
相当冗长,是吧?您可以滥用原型(prototype)中的所有方法都相同的事实来使其更短( Set
是一个具有短名称的内置函数):
[" test "].map(Set.call, ''.trim)
但即便如此,也不比通常的、可读的方式短:
[" test "].map(x => x.trim())
其中的奖金不是 forwarding unexpected arguments .
关于javascript - 为什么 JavaScript 的 `function.call` 必须显式调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51585707/