Подтвердить что ты не робот

Почему не будет передаваться `` '.trim() `прямо на` [].map() `callback work?

У меня есть массив строк. Я хочу обрезать каждую строку в массиве.

Я подумал, используя [].map() с ''.trim() будет работать...

[' a', ' b   ', 'c'].map(String.prototype.trim);

... но моя консоль сказала...

TypeError: String.prototype.trim вызывает null или undefined

jsFiddle.

Я не вижу никаких значений null или undefined в моем массиве.

String.prototype.trim() и Array.prototype.map() определены в Chrome 17, которые я использую для тестирования.

Почему это не работает? У меня такое чувство, что я забыл что-то очевидное.

Я понимаю, что я мог бы зациклиться или отбросить функцию там. Однако это не вопрос этого вопроса.

4b9b3361

Ответ 1

trim находится в прототипе String, что означает, что он будет иметь контекст this как строку, где в качестве метода map на Array предоставляется текущий элемент массива в качестве первого аргумента и контекст this является глобальным объектом.

Ответ 2

Что @Slace говорит, это правильное объяснение. @ThomasEding ответ также работает, но имеет одну ужасную inefficieny, что он может создавать функции внутри цикла, нехорошо делать.

Другой способ сделать: (ссылка здесь):

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

Стандартный отказ от браузера. Это будет работать везде, где Function.prototype.call и String.prototype.trim будут работать, а для старых браузеров вы можете легко заменить trim на polyfill следующим образом:

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

Обновление: в то время как это работает быстрее всего в Chrome, метод @ThomasEding работает немного быстрее в IE10 и FF20 - http://jsperf.com/native-trim-vs-regex-trim-vs-mixed p >

Ответ 3

Это потому, что trim не вызывается с соответствующим this контекстом. Помните, что this динамически связан в JS. Вам нужно будет создать обертку для перехода к trim для правильной привязки this:

[' a', ' b   ', 'c'].map(function (str) {
  return str.trim();
});

Ответ 4

С синтаксисом ES6 это может быть так просто:

[' hello  ', '  world'].map(str => str.trim());