Почему я не могу связать String.prototype.toLowerCase с underscore.js?
Я думаю, что проблема не в underscore.js, а в функциях собственных прототипов. Кажется, что их можно вызывать только напрямую, не передавая их как обратные вызовы. Вот код, который я не могу использовать, и ошибка из моих тестов (используя Mocha.js, только соответствующую часть):
_.chain("INPUT").tap(String.prototype.toLowerCase)
// => TypeError: String.prototype.toLowerCase called on null or undefined
Так попробовал это в REPL Node:
String.prototype.toLowerCase("INPUT")
// => ''
Я знаю, что нужно вызвать функцию прототипа с .call
или же .apply
а почему именно? И как я могу передать эту функцию в качестве обратного вызова?
2 ответа
Методы прототипа используют this
внутренне для ссылки на объект, которым нужно манипулировать.
call
а также apply
позволяет вам указать this
значение при вызове функции.
String.prototype.toLowerCase.call('INPUT'); //input
Если вы хотите связать this
значение для функции, так что ее форма вызова не имеет значения, вы можете сделать это с _.bind
или же Function.prototype.bind
,
var lowerCaseInput = String.prototype.toLowerCase.bind('INPUT');
lowerCaseInput(); //input
Теперь звоню _.chain
на объект обернет его в объект подчеркивания и возвращает обертку и _.tap
принимает в качестве входных данных результат предыдущей функции в цепочке. Прямо здесь мы видим, что это не будет работать, так как String.prototype.toLowerCase
даже не ожидает аргументов.
Не только это, но и строки являются неизменяемыми, поэтому вам придется сделать что-то вроде следующего:
_.chain({ text: 'INPUT' }).tap(function (obj) {
obj.text = obj.text.toLowerCase();
}).value().text;
Кроме того, если вы используете миксин, вы можете использовать mixin
это просто обертывания toLowerCase
,
_.mixin({
toLowerCase: function(str) {
// Add here any desired validation if wanted
return str.toLowerCase();
}
}, {
chain: false
});
После этого вы можете сделать что-то вроде:
_.chain('HELLO_WORLD')
.toLowerCase()
.replace('_',' ')
.value()