有时我使用Array.prototype.map方法,如下所示:
var array = ['1', '2', '3', '4'].map(parseFloat); // the result is [1, 2, 3, 4]
parseInt接受2个参数,在这种情况下返回不正确的值
现在我要做的是代替这个代码:
var array = ['a', 'b', 'c', 'd'].map( function (item) {
return item.toUpperCase();
}); // the result is ['A', B', 'C', 'D']
我试过这个:
var array = ['a', 'b', 'c', 'd'].map(''.toUpperCase.call);
有人能向我解释一下为什么我会得到一个错误,上面写着:吗
未捕获类型错误:["a","b","c","d"].map不是函数
第一个问题是传递函数''.toUpperCase.apply
,该函数与Function.prototype.apply
相同:它没有绑定。
发生的情况相当于
['a', 'b', 'c', 'd'].map(function(v, i, arr){
return undefined.apply(v, i, arr)
});
如果您使用进行绑定
['a', 'b', 'c', 'd'].map(''.toUpperCase.apply.bind(''.toUpperCase));
那么您会遇到第二个问题:map
不会只向回调传递一个参数。它还传递索引和整个数组。
你可以用"修复"这两个问题
['a', 'b', 'c', 'd'].map(function(v){ return ''.toUpperCase.apply(v) });
(与其说是修复,不如说是解释(
使用call
更容易,可以修复:
var arr = ['a', 'b', 'c', 'd'].map(''.toUpperCase.call.bind(''.toUpperCase));
应该写为
var arr = ['a', 'b', 'c', 'd'].map(Function.prototype.call.bind(''.toUpperCase));
旁注:您很幸运在第一个示例中使用了parseFloat
。尝试使用parseInt
。
当您将''.toUpperCase.call
传递给Array.map
时,尽管它会正确地传递参数,但call
函数与toUpperCase
函数分离,后者保存了实现细节。
因此,现在Function.call
确实有Array.map
回调函数传递给它的正确参数,但它没有引用''.toUpperCase
函数。
MDN:调用现有对象时,可以分配不同的
this
对象作用this
是指当前对象,是调用对象。
因此,''.toUpperCase.call("a")
与call("a")
完全不同,这就是当您将''.toUpperCase.call
传递给Array.map