Почему не будет передаваться `` '.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, которые я использую для тестирования.
Почему это не работает? У меня такое чувство, что я забыл что-то очевидное.
Я понимаю, что я мог бы зациклиться или отбросить функцию там. Однако это не вопрос этого вопроса.
Ответы
Ответ 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());