我有一个字符串," test "
。这是一个非常丑陋的字符串,所以让我们对其进行修剪。
" test ".trim()
返回"test"
。很好!
现在让我们尝试使用该字符串作为参数。
String.prototype.trim.call(" test ")
也返回"test"
。再次好!
哦,这意味着我可以使用String.prototype.trim.call
来通过它们对应的修剪字符串映射一个难看的字符串数组,对吧?
[" test "].map(String.prototype.trim.call)
不返回["test"]
。
它抛出TypeError: undefined is not a function
。
为什么不允许这样做?
答案 0 :(得分:1)
所有函数call
方法都具有相同的函数值:
> String.prototype.trim.call === Function.prototype.call
true
> String.prototype.trim.call === alert.call
true
要调用的函数作为其Function.prototype.call
值传递给this
。函数调用varies depending on how the call is made的this
值:
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
值。
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)
非常冗长,是吗?您可能会滥用这样一个事实,即原型中的所有方法都等同于使其变得更短(Set
是带有短名称的内置函数):
[" test "].map(Set.call, ''.trim)
但即使如此,它也不会比通常的可读方式短:
[" test "].map(x => x.trim())