I’m just getting into Backbone, and one thing that I don’t understand is why the ‘on()’ method for models always takes three arguments–event, handler, and context.
It seems that almost always ‘this’ is used for context and I haven’t seen any other usage. Even if there were, since I haven’t seen one yet it must be pretty rare.
So my question is: When does one use a context other than ‘this’, and why is Backbone designed this way? By the way, I do understand why you need to provide context, it’s just that I wonder why the method syntax specifies that I use three arguments instead of making the last argument optional–which seems to be always ‘this’ and feels redundant. I’m sure I’m missing something. Please someone help me understand. Thank you!
-
[EDIT] Why can’t one do something like:
model.on = function(event, callback){ model.on_with_three_args.call(this, event, callback, this); }); model.on_with_three_args = function(event, callback){ /* whatever the on() is supposed to do */ });
Suppose we’re in a view that’s based on a model and we want to bind to the model’s change event:
The
oncall sees two things:onhas no way of knowing whatthismeans inthis.render, it just sees a function;onwon’t even know the difference between the call above and this:If your function needs a particular context then you have two choices:
_.bind,_.bindAll,Function.bind,$.proxy, CoffeeScripts=>, thevar _this = thisclosure trick, or any of the ways of creating or simulating a bound function.Tell it which context you want by saying:
There’s no way to unroll the call stack to see which
thisyou want so you have to be explicit about it.Backbone will call the callback like this:
where
node.callbackis the callback function andnode.contextis the third argument (if any) given toon. If you don’t specify the context then you’ll get whateverthishappens to be whentriggeris called; in the example above,thiswould end up being the model.So the third argument to
onactually is optional but the default value isn’t terribly useful and there is no way to choose a better default, the information you need to choose a sensible context simply isn’t accessible in JavaScript. This is why you see so much_.bindAll(this, ...)boilerplate in Backbone views.If you tried something like this:
then
thisin that context would usually bemodelso you’d really be saying:or
and there’s little point to any of that. The value of
thisinsideonhas little if anything to do with the value ofthisin the code that callson.thisin JavaScript is not a variable, it is a keyword which refers to the current calling context.