为什么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())