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.apply
which 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: map
doesn'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 call
is 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 parseFloat
in the first example. Try with parseInt
.
旁注:您很幸运parseFloat
在第一个示例中使用。尝试使用parseInt
.
回答by Amit Joki
When you pass ''.toUpperCase.call
to Array.map
, though it will pass the argument correctly, the call
function disintegrates from toUpperCase
function, which holds the implementation details.
当您传递''.toUpperCase.call
到 时Array.map
,尽管它会正确传递参数,但该call
函数会从toUpperCase
保存实现细节的函数中解体。
So, now the Function.call
does have the correct argument passed to it by the Array.map
callback function, but it holds no reference to ''.toUpperCase
function.
所以,现在Function.call
确实有Array.map
回调函数传递给它的正确参数,但它没有对''.toUpperCase
函数的引用。
MDN:You can assign a different
this
object when calling an existing function.this
refers 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.call
to Array.map
So''.toUpperCase.call("a")
与 完全不同call("a")
,这就是当您传递''.toUpperCase.call
给Array.map