Reputation: 1604
I think the issue is not with underscore.js, but rather with Native prototypes functions. It seems that one can only call them directly, not passing them as callbacks. Here's the code the I can't use and the error from my tests (using Mocha.js, only the relevant portion):
_.chain("INPUT").tap(String.prototype.toLowerCase)
// => TypeError: String.prototype.toLowerCase called on null or undefined
So tried this in Node's REPL :
String.prototype.toLowerCase("INPUT")
// => ''
I know one should call a prototype's function with .call
or .apply
, but why exactly ? And how can I pass this function as a callback ?
Upvotes: 1
Views: 2534
Reputation: 465
Additionally, if you use mixins, you can use a mixin
that simply wraps toLowerCase
.
_.mixin({
toLowerCase: function(str) {
// Add here any desired validation if wanted
return str.toLowerCase();
}
}, {
chain: false
});
After, you can do something like:
_.chain('HELLO_WORLD')
.toLowerCase()
.replace('_',' ')
.value()
Upvotes: 0
Reputation: 43718
Prototype methods are using this
internally to refer to the object that should get manipulated.
call
and apply
lets you specify the this
value when calling a function.
String.prototype.toLowerCase.call('INPUT'); //input
If you want to bind a this
value to a function so that it's invocation form doesn't matter, you can do it with _.bind
or Function.prototype.bind
.
var lowerCaseInput = String.prototype.toLowerCase.bind('INPUT');
lowerCaseInput(); //input
Now, calling _.chain
on an object will wrap it in an underscore object and returns the wrapper and _.tap
takes the result of the previous function in the chain as it's input. Right here we see it's not going to work since String.prototype.toLowerCase
doesn't even expect arguments.
Not only this, but strings are immutable so you would have to do something like the following:
_.chain({ text: 'INPUT' }).tap(function (obj) {
obj.text = obj.text.toLowerCase();
}).value().text;
Upvotes: 2