Today while writing code using underscore and backbone i had to wrap some functions. I saw following example on underscorejs.org
var hello = function(name) { return "hello: " + name; };
hello = _.wrap(hello, function(func) {
return "before, " + func("moe") + ", after";
});
hello();
=> 'before, hello: moe, after'
on the second last line
what if the function call is like
hello("umar");
I means to say that arguments are coming from outside.
Wrap already takes care of most of this for you. The source for wrap is pretty short to read through. That or you can take a gander at the extended example below:
var greet = function(name, language){
var response
if (language === "sp") {
response = "Hola"
} else if (language === "fr") {
response = "Bonjour"
} else {
response = "Hello"
}
return response + " " + name
}
greet("Ted", "fr"); // => "Bonjour Ted"
greet = _.wrap(greet, function(old_greet, lang){ return old_greet("Ted", lang); } );
greet("sp"); // => "Hola Ted"
Thanks for this quick response. It was very much helpful.
I am using backbone to develop an enterprise app.
view.js
var view = Backbone.View.extend({
authorizeCreateAction: function (){
//here "this" points to view
this.createAlert: _.wrap(this.createAlert, function(_createAlert, _type){
//authorize create action
return _createAlert(_type);
});
},
createAlert: function(type){
//PROBLEM:
// Here "this" points to [window global]
}
});
see inside createAlert function when I was calling createAlert function directally it was pointing to view but when I wrote wrapper function it started pointing to [window global]
I want to change referance of this to be pointing to "view"
I am new to underscore, please ignore if question is irrelevant.
BTW underscore is awesome
You'll need to call _createAlert
with a context like below. Hope that helps. :)
return _createAlert.call(this, _type);
it seems underscore _wrap only supports one parameter , use this instead:
fn = (function(fn,before,after, self) {
return function() {
if(before) before.apply(self,arguments);
var res = fn.apply(self,arguments);
if(after) after.apply(self,arguments);
return res;
}
})(fn, before, after, this )
You can also use partial for that zarehb
tnx megawac, partial is more for pre-filling the arguments not calling a before and after function
Wrap is implemented via _.partial
fyi
fn = _.partial(function(fn, before, after, self) {
var args = _.rest(arguments, 4);
if (before) before.apply(self,args);
var res = fn.apply(self,args);
if (after) after.apply(self,args);
return res;
})(fn, before, after, this )
that's correct and it will work, but in case anyone wants a pure js solution can take mine specially that using underscore doesn't give you any benefit in this case!