为什么JavaScript';s`function.call`必须显式调用吗?
我有一个字符串,为什么JavaScript';s`function.call`必须显式调用吗?,javascript,prototype,method-call,Javascript,Prototype,Method Call,我有一个字符串,“test”。这是一根非常难看的绳子,让我们修剪一下吧 “test”.trim()返回“test”。很好 现在,让我们尝试使用该字符串作为参数 String.prototype.trim.call(“test”)还返回“test”。又好了 哦,这意味着我可以使用String.prototype.trim.call将一组丑陋的字符串映射到经过修剪的对应字符串,对吗 [“test”].map(String.prototype.trim.call)不返回[“test”] 它抛出类型错误
“test”
。这是一根非常难看的绳子,让我们修剪一下吧
“test”.trim()返回“test”
。很好
现在,让我们尝试使用该字符串作为参数
String.prototype.trim.call(“test”)
还返回“test”
。又好了
哦,这意味着我可以使用String.prototype.trim.call
将一组丑陋的字符串映射到经过修剪的对应字符串,对吗
[“test”].map(String.prototype.trim.call)
不返回[“test”]
它抛出类型错误:未定义不是函数
为什么不允许这样做?所有函数调用方法都是相同的函数值:
> String.prototype.trim.call === Function.prototype.call
true
> String.prototype.trim.call === alert.call
true
要调用的函数被传递给function.prototype.call
作为它的此
值。函数调用的此
值:
在所有非调用的情况下引用函数时,不涉及此值
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
调用它(undefined
,因为您只传递了一个参数)Function.prototype.call
调用它所给定的这个
值,因为它不能调用未定义的
,所以失败
通过将this
的正确值作为thisArg
传递,可以修复代码:
[" test "].map(String.prototype.trim.call, String.prototype.trim)
非常冗长,是吗?您可以滥用这样一个事实,即原型中的所有方法都相等,从而使其变得更短(Set
是一个具有短名称的内置函数):
但即使这样也不比通常的可读方式短:
[" test "].map(x => x.trim())
它的优点是不。.map(String.prototype.trim.call)
传递调用
方法,而不包含String.prototype.trim的上下文。尝试使用普通的箭头函数或类似于String.prototype.trim.bind(String.prototype)
的函数。
[" test "].map(Set.call, ''.trim)
[" test "].map(x => x.trim())