为什么不将`''..(简单)直接传递给`[] .map()`的回调工作?

ale*_*lex 25 javascript

我有一个字符串数组.我想修剪数组中的每个字符串.

我想用[].map()''.trim()会工作...

[' a', ' b   ', 'c'].map(String.prototype.trim);
Run Code Online (Sandbox Code Playgroud)

......但我的控制台说......

TypeError:String.prototype.trim在null或undefined上调用

jsFiddle.

我在数组中看不到任何nullundefined值.

String.prototype.trim()Array.prototype.map()在Chrome 17中定义,我正在测试.

为什么这不起作用?我觉得我忽略了一些显而易见的事情.

我意识到我可以在那里循环或删除一个函数.然而,这不是这个问题的重点.

Mrc*_*ief 35

@Slace所说的是正确的解释.@ ThomasEding的答案也有效,但有一个可怕的低效率,它可能在循环中创建函数,这不是一件好事.

另一种做法是(参考这里):

[' a', ' b   ', 'c'].map(Function.prototype.call, String.prototype.trim);  
// gives ["a", "b", "c"]
Run Code Online (Sandbox Code Playgroud)

标准的浏览器免责声明:这将工作的地方Function.prototype.call,并String.prototype.trim会工作,为旧的浏览器,你可以很容易地替换trim填充工具是这样的:

if(!String.prototype.trim) {  
  String.prototype.trim = function () {  
    return this.replace(/^\s+|\s+$/g,'');  
  };  
}
Run Code Online (Sandbox Code Playgroud)

更新:Interstingly,虽然这在Chrome中运行速度最快,但ThomasEding的方法在IE10和FF20中的运行速度稍快 - http://jsperf.com/native-trim-vs-regex-trim-vs-mixed


Tho*_*ing 25

那是因为trim没有使用适当的this上下文调用.请记住,它this是在JS中动态绑定的.您必须创建一个包装器以传递trim给正确绑定this:

[' a', ' b   ', 'c'].map(function (str) {
  return str.trim();
});
Run Code Online (Sandbox Code Playgroud)

  • @Mrchief:这是实现地图的一种方式.另一种是通过递归.在任何一种情况下,如何实现地图都没有实际意义.在这种情况下,该功能仅创建一次.然后将指向函数的指针传递给map,map使用与其工作相同的引用. (4认同)
  • 谢谢回答.我想我经常使用jQuery的`$ .trim()`. (2认同)
  • @Mrchief:上面的代码没有这样做.如果您使用我现有的代码并在循环中抛出它... (2认同)

Aar*_*ell 19

trimString原型上,意味着它期望this上下文是字符串的上下文,因为map方法on Array将当前数组项提供为第一个参数,this上下文是全局对象.

  • @nrabinowitz:`apply`的`this`没有绑定到`String.prototype.trim` - 它被绑定到`undefined`或`null`或`window`.(这就是他们发明`Function.bind()`的原因.) (5认同)
  • 那为什么这不起作用?`['a','b','c'].map(String.prototype.trim.apply);`...以及为什么这在`map()`上下文之外工作?`String.prototype.trim('a')`(注意它实际上不工作* - 返回一个空字符串 - 但它也不会抛出错误.) (2认同)