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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 12:24:09  来源:igfitidea点击:

Array.prototype.map is not a function when passing a function generated by Function.prototype.call as argument

javascriptarrays

提问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.callArray.map