javascript - 为什么 JavaScript 的 `function.call` 必须显式调用?

标签 javascript prototype method-call

我有一个字符串,“测试”。这是一条非常丑陋的字符串,所以让我们 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/

相关文章:

Java调用方法打印类列表

javascript - jQuery elevateZoom 插件 - 图像居中

javascript - 原型(prototype)javascript混淆

javascript - 在渲染路线之前在 Ember 中请求

javascript - iPad HTML 原型(prototype) : Which JS Framework?

C 函数调用中的 C 原型(prototype)函数和默认参数提升

java对多个对象的方法调用

java - Mockito:验证来自内部匿名类的方法调用

javascript - 如何从另一个页面获取内容

javascript - 为什么 -1 是假的? - 为了 (