javascript 传递由 Function.prototype.call 生成的函数作为参数时,Array.prototype.map 不是函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30594471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Array.prototype.map is not a function when passing a function generated by Function.prototype.call as argument
提问by Khalid
Sometimes I use the Array.prototype.map methode like so :
有时我像这样使用 Array.prototype.map 方法:
var array = ['1', '2', '3', '4'].map(parseFloat); // the result is [1, 2, 3, 4]
parseInttakes 2 arguments it returns incorrect values in this case
parseInt需要 2 个参数,在这种情况下它返回不正确的值
Now what I'm trying to do is instead of this code :
现在我要做的是而不是这个代码:
var array = ['a', 'b', 'c', 'd'].map( function (item) {
return item.toUpperCase();
}); // the result is ['A', B', 'C', 'D']
I tried this :
我试过这个:
var array = ['a', 'b', 'c', 'd'].map(''.toUpperCase.call);
can someone explain to me why I get an error that says :
有人可以向我解释为什么我收到错误消息:
Uncaught TypeError: ["a","b","c","d"].map is not a function
未捕获的类型错误:["a","b","c","d"].map 不是函数
采纳答案by Denys Séguret
The first problem is you pass the function ''.toUpperCase.applywhich is the sameas Function.prototype.apply: it isn't bound.
第一个问题是你传递的功能''.toUpperCase.apply这是一样的Function.prototype.apply:它不绑定。
What happens is equivalent to
发生的事情相当于
['a', 'b', 'c', 'd'].map(function(v, i, arr){
return undefined.apply(v, i, arr)
});
If you bind it using
如果您使用绑定它
['a', 'b', 'c', 'd'].map(''.toUpperCase.apply.bind(''.toUpperCase));
then you have a second problem: mapdoesn't pass only one parameter to your callback. It also pass the index and the whole array.
那么你有第二个问题:map不会只传递一个参数给你的回调。它还传递索引和整个数组。
You could "fix" the two problems with
你可以“修复”这两个问题
['a', 'b', 'c', 'd'].map(function(v){ return ''.toUpperCase.apply(v) });
(more an explanation than a fix, right)
(与其说是修复,不如说是解释,对)
Using callis easier and canbe fixed:
使用call更容易并且可以修复:
var arr = ['a', 'b', 'c', 'd'].map(''.toUpperCase.call.bind(''.toUpperCase));
which should be written as
应该写成
var arr = ['a', 'b', 'c', 'd'].map(Function.prototype.call.bind(''.toUpperCase));
Side note:you were lucky to use parseFloatin the first example. Try with parseInt.
旁注:您很幸运parseFloat在第一个示例中使用。尝试使用parseInt.
回答by Amit Joki
When you pass ''.toUpperCase.callto Array.map, though it will pass the argument correctly, the callfunction disintegrates from toUpperCasefunction, which holds the implementation details.
当您传递''.toUpperCase.call到 时Array.map,尽管它会正确传递参数,但该call函数会从toUpperCase保存实现细节的函数中解体。
So, now the Function.calldoes have the correct argument passed to it by the Array.mapcallback function, but it holds no reference to ''.toUpperCasefunction.
所以,现在Function.call确实有Array.map回调函数传递给它的正确参数,但它没有对''.toUpperCase函数的引用。
MDN:You can assign a different
thisobject when calling an existing function.thisrefers to the current object, the calling object.
MDN:您可以
this在调用现有函数时分配不同的对象。this指的是当前对象,调用对象。
So ''.toUpperCase.call("a")is entirely different to call("a"), which is what is happening when you pass ''.toUpperCase.callto Array.map
So''.toUpperCase.call("a")与 完全不同call("a"),这就是当您传递''.toUpperCase.call给Array.map

