简体   繁体   English

如何将原型上定义的方法传递给Array.map作为回调

[英]How to pass the method defined on prototype to Array.map as callback

I have an array 我有一个阵列

var arr = [' A ', ' b ', 'c'];

and I want to trim the spaces from each of the element from array. 我想从数组中trim每个元素的空格。

It can be done by using Array.map as 可以使用Array.map作为

arr.map(function(el) {
    return el.trim();
});

I'm curious about passing the trim / toLowerCase function directly to the map as callback function, like arr.map(Math.max.apply.bind(Math.max, null)); 我很好奇将trim / toLowerCase函数直接传递给map作为回调函数,如arr.map(Math.max.apply.bind(Math.max,null)); to get the maximum element from each subarray or arr.map(Number); 从每个子数组arr.map(Number)获取最大元素; to cast each element to Number. 将每个元素转换为Number。

I've tried 我试过了

arr.map(String.prototype.trim.apply);

but it is throwing error 但这是投掷错误

Uncaught TypeError: Function.prototype.apply was called on undefined, which is a undefined and not a function 未捕获的TypeError:在undefined上调用了Function.prototype.apply,这是一个未定义的而不是函数

I expect that String.prototype.trim.apply should be called for each element in the array with the context set to the element from array(passed to apply ); 我希望应该为数组中的每个元素调用String.prototype.trim.apply ,并将上下文设置为array中的元素(传递给apply );

I've also tried different combinations of apply , call and bind with no success. 我也尝试过applycallbind不同组合,但没有成功。

  1. Why the function on prototype cannot be referenced when using map 为什么使用map时无法引用原型上的函数
  2. How function can be passed as parameter to map 函数如何作为参数传递给map
arr.map(String.prototype.trim.call.bind(String.prototype.trim));

call uses this internally, which must point to the trim function to work properly in this case. call this内部使用this ,在这种情况下必须指向trim函数才能正常工作。 Simply passing String.prototype.trim.call would leave call unbound to any method, resulting in the this value pointing to window instead. 只需传递String.prototype.trim.call就可以将call解除绑定到任何方法,从而导致this值指向window

It works, but when used apply instead of call it throws error, arr.map(String.prototype.trim.apply.bind(String.prototype.trim)); 它可以工作,但是当使用apply而不是call它抛出错误时,arr.map(String.prototype.trim.apply.bind(String.prototype.trim));

The problem is that map will pass 2 arguments, the item and the index. 问题是map将传递2个参数,即项和索引。 Therefore it ends up calling something like 'String.prototype.trim.apply('test', 0) which fails since the second argument must be an array. 因此,它最终会调用类似'String.prototype.trim.apply('test', 0) ,因为第二个参数必须是数组才会失败。

one more thing [' A ', ' B ', 'c'].map(String.prototype.trim.call.bind(String.prototype.toLowerCase));, in this, I've used trim.call and passed toLowerCase as context then why we need trim here, why trim is not called 还有一件事['A','B','c']。map(String.prototype.trim.call.bind(String.prototype.toLowerCase));,在这里,我使用了trim.call并传递了toLowerCase作为上下文然后为什么我们需要修剪这里,为什么不调用trim

When using call.bind the path that you chose to access the call function reference becomes irrelevant. 使用call.bind ,您选择访问call函数引用的路径变得无关紧要。 The function that will get called is the one that is bound. 将被调用的函数是绑定的函数。

If you want to compose functions together you will need a different approach: 如果要将功能组合在一起,则需要采用不同的方法:

var call = Function.prototype.call,
    trim = call.bind(String.prototype.trim),
    toLowerCase = call.bind(String.prototype.toLowerCase),
    trimAndLowerCase = pipelineFrom(trim, toLowerCase);

[' TeST '].map(trimAndLowerCase);

function pipelineFrom(fn1, fn2) {
    return function (val) {
        return fn2(fn1(val));
    };
}

However at this point you're better off with: 但是在这一点上你最好用:

arr.map(function (val) {
    return val.trim().toLowerCase();
});

This works, it sure is long-winded though: 这有效,但肯定是啰嗦:

var t = String.prototype.trim.call.bind(String.prototype.trim);
arr.map(t);

Because it's longwinded there are blog posts and modules devoted to uncurrying, which is what you are trying to do here. 因为它很长,所以有博客文章模块专门用于解决,这就是你想要做的事情。

I did ask about this here once... 我曾经在这里问过这件事 ......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM