为什么不[“A”,“B”,“C”]。map(String.prototype.toLowerCase.call)有效吗?

时间:2014-04-24 22:25:22

标签: javascript

当然,这会返回您的期望:

["A","B","C"].map(function (x) {
    return x.toLowerCase();
});
// --> ["a", "b", "c"]

使用String.prototype.toLowerCase.call:

["A","B","C"].map(function (x) {
    return String.prototype.toLowerCase.call(x);
});
// --> ["a", "b", "c"]

如果你传递map给出的额外参数,它也会起作用,因为它抛弃了参数:

["A","B","C"].map(function (x, index, arr) {
    return String.prototype.toLowerCase.call(x, index, arr);
});
// --> ["a", "b", "c"]

但是,这不起作用:

["A","B","C"].map(String.prototype.toLowerCase.call);
// --> TypeError: undefined is not a function

以下也不起作用,因为arguments具有Object原型而不是Array原型,因此slice未定义。上述行为的原因可能是因为这样的事情 - 在内部使用slice或其他类似的Array函数?

["A","B","C"].map(function (x) {
    return String.prototype.toLowerCase.apply(x, arguments.slice(1));
});
// --> TypeError: undefined is not a function

4 个答案:

答案 0 :(得分:25)

类似问题:Why won't passing `''.trim()` straight to `[].map()`'s callback work?

Map有一个可选的thisArg,可以这样使用:

['A', 'B', 'C'].map(Function.prototype.call, String.prototype.toLowerCase);  
// gives ["a", "b", "c"]

答案 1 :(得分:13)

这是JavaScript的点符号的特殊行为。

toLowerCase.call(x)正在运行,因为JavaScript在执行toLowerCase时使用this作为call。这就是call(您在每个函数上找到的Function.prototype.call)知道您希望它执行toLowerCase的方式。

call传递到另一个函数会丢失该引用,因此this不再引用toLowerCase

答案 2 :(得分:5)

问题在于String.prototype.toLowerCase.call == Function.prototype.call。如果要获取将参数转换为小写的函数,可以将toLowerCase函数绑定到call函数,如下所示:

var toLowerCase = String.prototype.toLowerCase.call.bind(String.prototype.toLowerCase);
["A","B","C"].map(toLowerCase);

答案 3 :(得分:2)

  

但是,这不起作用:

     

[ “A”, “B”, “C”]图(String.prototype.toLowerCase.call);

传递给map的第一个参数应该是一个将传递数组成员值的函数。以上内容直接引用 Function.prototype.call ,因此该函数将尝试:

call(x);

所以调用已经通过而没有设置 this ,因此在进入调用函数时它将是 undefined