Comments on Getting Out of Binding Situations in JavaScript

54 Reader Comments

Back to the Article
  1. Binding is never required but could save certain issues for sure.

    Copy & paste the code below to embed this comment.
  2. This was a very informative article - I was previously unaware of apply and call in javascript, and had been using lexical closures to preserve binding where I needed it - and in some cases, this was quite clunky.

    Thanks for the info!

    Copy & paste the code below to embed this comment.
  3. The excellent YUI library does this as well, both in event binding, and for instance YAHOO.lang.later (too preserve scope in window.setTimeout/Interval).

    Copy & paste the code below to embed this comment.

  4. name = 'Ray'; // Or explictly: window.name = 'Ray';
    var john = {
    name: 'John',
    greet: function(person) {
    with(this)
    alert("Hi " + person + ", my name is " + name);
    }
    };

    john.greet("Mark");
    // => "Hi Mark, my name is John"

    Copy & paste the code below to embed this comment.
  5. I’m the “var that = this” kind of person (actually, var scope = this).

    Scope, and object oriented programming in Javascript in general, has cost me many headaches. This articles gives extra insight and explains binding in a very clear way. Thank you Christophe!

    Copy & paste the code below to embed this comment.
  6. Thank you, it’s very helpful to have related programming tricks brought together like this. In JavaScript you need them to do practically anything more advanced with objects, yet you won’t find it in any language reference — because it’s a usage pattern, not part of the syntax…

    I’m pretty new to JavaScript, and I have stumbled upon this problem several times already. Solved it with “var that=this” following Douglas Crowford, but creating a helper function might have been much more convenient in many cases.

    Thank you.

    Copy & paste the code below to embed this comment.
  7. One of the best technical articles I’ve read in a year.  The clarity, level of detail, and the flow from low level to high level is just brilliant.

    Thank you.  I wish all technical material was in this tone and level.

    Copy & paste the code below to embed this comment.
  8. I have read every alistapart article, and I absolutely love this site, but I still have to say, I’m so sick of everyone from the train-yard bagging PHP. I feel so much animosity from RoR as if there was a war between two of the most promising open source programming solutions. Every time an article is written about OOP PHP is bagged. PHP is much (5 times) faster than Ruby, which is one reason why development of PHP, and new users are growing at such an alarming rate.

    Copy & paste the code below to embed this comment.
  9. Huh, dude? How the hell did you manage to draw that conclusion from an article focusing on Javascript?

    Copy & paste the code below to embed this comment.
  10. The explanation of using append=true in the section on ExtJS and createDelegate is not partial application, not in the way the article uses the term everywhere else at least (the difference is parenthetically explained but not particularly clearly to my mind). Getting partial application with ExtJS seems to require (judging solely by the content of the article as I’ve not used it myself) using 0 as the insertion position.

    I’m assuming that the section on apply was intended to be indicating that wrapping functions can be made generic since apply takes an array and as such the wrapping function doesn’t need to know what the actual argument list for the wrapped function is, but that is not at all clear to me.  It seems to me that that section, as written, could be read to indicate that apply doesn’t care what order the arguments are in the array and that the function will Just Work, a conclusion that is not at all correct. This may want some clarification in the article.

    Copy & paste the code below to embed this comment.
  11. I hate being “that mootools” guy that always pops up in the comments, but I do wish you woulda thrown in a bit about how mootools bind and closure functions[1] work.  It’s bind() and bindWithEvent() functions are extremely useful for binding objects.


    [1]http://docs.mootools.net/Native/Function

    Copy & paste the code below to embed this comment.
  12. Edit, missed that the comment board uses textile. 

    I do wish you would of thrown in a bit about how mootools “bind and closure functions”:http://docs.mootools.net/Native/Function work.

    Copy & paste the code below to embed this comment.
  13. Good article.  Having had to explain js binding on more than one occasion, it’s nice to have a good explanation written down that I can just link to.

    One point that I think would have been beneficial to spell out more explicitly is that ‘this’ is resolved at execution time and will refer to
    1) the object provided as first param to call/apply when invoked that way,
    2) the object from which the “method was referenced”:http://pastie.org/226696 (luke.fn = john.greet; luke.fn(“Joe”); // this === luke)
    3) From a “with block”:http://pastie.org/226686 , but please PLEASE don’t do it
    4) the global object (window in browsers) when not invoked from an object.

    And a special note: ‘this’ can refer to more than just objects:
    var greet = function (a) { return 'Hi ' + a; };
    greet.from = function (a,b) { alert(this(a) + ", I'm " + b); };

    greet.from(‘Christophe’,‘John’); // this resolves to the function greet

    (I’m not suggesting this is good practice, just functional—no pun intended)

    Copy & paste the code below to embed this comment.
  14. Yeah, the comment preview isn’t quite wysiwyg.  Hope that was readable enough.

    Copy & paste the code below to embed this comment.
  15. bq. Also, if we walk the line, functions in JS are”¦ objects. So yes, this references objects :-)

    Touche :-)

    Of course you understood what I meant (typeof !== ‘object’ vs instanceof Object).

    While we’re being pedantic, it may also be worth noting (or maybe not) that primitives are converted to their respective String/Number/Boolean object types if passed as the context in call/apply.  Passing null/undefined will cause this === global object (window).  So yes, this will always refer to an instanceof Object.  At least to the best of my knowledge.

    function fn() { alert(this instanceof String); }

    fn.call(“string literal, not instanceof String”); // alerts ‘true’

    Of course, that sort of code is best avoided (to say the least).

    Copy & paste the code below to embed this comment.
  16. Great article—I’ve been wondering for a while when ALA(A List Apart) would get onto this! Besides, I always prefer the articles about code to the more philosophical essays.

    Since you mentioned Prototype’s @bind@ function, it’s only fair to give honourable mention to Daniel Brockman, upon whose code it seems to be modelled. He wrote “an excellent article(Object-Oriented Event Listening through Partial Application in JavaScript)”:http://www.brockman.se/writing/method-references.html.utf8 about the binding problem, with particular reference to event listeners, back in 2004. I’ve been employing his solution to good effect for the past couple of years.

    Copy & paste the code below to embed this comment.
  17. Good article that illuminates JavaScript’s more powerful OO functionality. Personally I like how binding abstracts execution from data, allowing a coder to write objects that are like a cross between an abstract class and an interface. Implementations are not differentiated by distinct code but by the data they operate on, aka context. Here’s using your example:

    function Person(first, last, age) {
      this.first = first;
      this.last = last;
      this.age = age;
    }

    Person.prototype = {
      _getFullName: function() {
        alert(this.first + ' ' + this.last);
      },
      _greet: function(other) {
        alert("Hi " + other.first + ", I'm " + »
        this.first + ".");
      }
    };

    var elodie = {
      ___proto___: new Person('Elodie', 'Jaubert', 27),
      getFullName: function() { elodie._getFullName.call(elodie); },
      greet: function(other) { elodie._greet.call(elodie, other); }
    };

    For the memory-leak conscious, this implementation is also closure-free.

    Copy & paste the code below to embed this comment.
  18. Also thwarted by the preview, here’s the formatted code at Pastie:

    http://pastie.org/227266

    Copy & paste the code below to embed this comment.
  19. Here’s my reason: closures are hard to conceptualize and, because of their implicit declaration, often completely missed. To a strict and unaware programmer, closures can make broken-looking code seem to “magically” work. And with an extremely popular browser that can’t handle closures properly, my good practices are to avoid them altogether. The goal is to write code that can be used anywhere over and over without detriment, ie programming to interfaces.

    Therefore explicitly assigning the prototype chain to a parent class reinforces the idea of prototyping as inheritance as opposed to the more common use of simple declaration.

    As far as alternative practices, you correctly pointed out that “[extra] _method calls are costly_”. And really, you are saying “var that = this;” isn’t convoluted at all :-}?

    Copy & paste the code below to embed this comment.
  20. I often find it simpler to build into the function arguments an instance variable, and then on call, pass this.

    function cool(instance)
    {
    alert(instance.reason);
    }

    Then I just execute cool(this).

    Would there be good reason NOT to do this? (outside the debate of closures)

    Copy & paste the code below to embed this comment.
  21. Hi Christophe, great article.  It prompted a lot of discussion with co-workers.

    I have a question (or two).  I’m not a javascript expert, but I read (skim) a lot of articles that usually tell me enough to get by.  When I read your section on recognizing patterns, I wrote up a solution which avoids the problems using a closure.  (I won’t try to paste it, it’s here: “http://pastie.org/228035”:http://pastie.org/228035 ).

    So I know you’re using prototypal inheritance, and I’m not sure what I’m using… but I do know…  your method, while being easier to understand, still has to deal with the binding problems, and allows direct access to it’s properties.  While mine solves both.  I also know that you probably know a lot more than I do.

    So, (finally) getting to my questions, is there a reason why you choose to use prototypal instead of a method using closures? Are there performance issues or something that I am unaware of?  I’m curious, because while I have seen things comparing method with the other, I haven’t really come across anything which tells me _why_ one method is better than another, or one should be used rather than the other.  I’m interested in your thoughts.

    Copy & paste the code below to embed this comment.
  22. Christophe, writing a function to accept the object instance as an argument most certainly *can* be object-oriented; one need only look at Python for an example (it’s hard to argue Python isn’t an OO language, seeing as everything in Python is an object and the “under the hood” way the language works is based entirely around invoking methods of objects).

    Your argument that this hurts “programming in the large”, then, would seem to be contradicted by reality, because there are plenty of large applications and systems of applications written in Python. This leaves the subjective argument which, really, seems to be the only argument there is against this style; I personally don’t have any problems with the fact that Python requires ‘self’ to be declared as an argument, and it certainly has some advantages (in terms of regularity and simplification of the language and working with the language).

    Copy & paste the code below to embed this comment.
  23. Sorry if I missed this in someone else’s comment, and I’m sure I’m wrong, because this must have been thought of already, but what about binding with a syntax similar to the static binding in Java, Ruby, and even PHP?

    So why not:

    var Christophe = {
    name: 'Christophe',
    hi:function() {
    alert("Hi! My name is" + Christophe.name + "!");
    }
    }

    Christophe.hi()
    # Should give you a box with “Hi! My name is Christophe!”

    var fx = Christophe.hi
    fx()
    # Haven’t actually tested this. Will it fail, too?

    Copy & paste the code below to embed this comment.
  24. Should be a line break before the fx().

    Copy & paste the code below to embed this comment.
  25. I see where mine would fail after looking at the article again—instantiation (makes sense, duh).

    Copy & paste the code below to embed this comment.
  26. I’ve been playing with it some more, and my question is this: how often do you find yourself needing to pass a method reference instead of a reference to an object that will ultimately perform the method? I’m sure you have plenty of examples and that’s why you wrote this, but I’m mainly curious to hear about some of them. When would you need such an abstract “method launcher”?

    Copy & paste the code below to embed this comment.
  27. Thanks for the replies, Christophe. Makes perfect sense now, though makes me feel like I wish web tech didn’t move at the speed of molasses. If only all browsers supported a JavaScript based on some of the more recent ECMA specs (even Actionscript is a better implementation at this point).

    Copy & paste the code below to embed this comment.
  28. I actually over simplified my example, here’s an example:

    var MyGame = function(){...};

    myGame.prototype.Interact = function()
    {
    var quickCheck = function(instance){...A quick function only used by Interact with instance, only required in Interact…}
    /* ...do some stuff… */

    quickCheck(this);
    }

    The idea would be a I create these mini functions within my prototype objects to perform various tasks that would be repeated multiple times throughout Interact.

    (Bear with me a bit here as I feel I can get quite a bit done in javascript but some of my definitions/verbage may be a bit noob :) )

    Copy & paste the code below to embed this comment.
  29. looks like my comment formatting got borked :)

    Copy & paste the code below to embed this comment.
  30. looks like my comment formatting got borked :)

    Copy & paste the code below to embed this comment.
  31. Nice article! I particularly appreciate that you covered all the basics, and even mentioned when certain patterns weren’t necessary. Hopefully this will help alleviate some of the ignorance about the language out there. Thanks!

    Copy & paste the code below to embed this comment.
  32. as #8 mentioned, i love ala but i have to say that i stop reading any article when it begins with php is bad….

    Copy & paste the code below to embed this comment.
  33. I found this article incredible helpful. I’m saving it for later, can’t remember how many times I’ve had this problems while OOPing with Javascript.
    I resorted to use prototype binding functions, but i find (my) solutions rather un-elegant.
    Christophe, what book would you recommend to learn OOP in Javascript?

    Copy & paste the code below to embed this comment.
  34. Hello, Christophe!
    Thanks for this great article. I have translated it into Russian. I hope you don’t mind :) The link is http://habrahabr.ru/blog/javascript/46773.html

    Copy & paste the code below to embed this comment.
  35. Hi Christophe,

    Really nicely written, thanks a ton! Just another (interesting?) fact that I noticed is that if we pass the method reference (method belongs to say obj1) to another object’s member (say this object is obj2), the “this” keyword inside the passed method would now refer to the second object obj2. here is the snippet (i think the formatting will get lost, but anyways)

    name = 'Ray'; // Or explictly: window.name = 'Ray';
    var john = {
      name: 'John',
      greet: function(person) {
        alert("Hi " + person + ", my name is " + this.name);
      }
    };

    var doe = {
      name: 'Doe',
      fx: john.greet
    };

    doe.fx("Mark"); 
    Copy & paste the code below to embed this comment.
  36. Sorry trying again to get the formatting correct this time (keeping my fingers crossed! ;) )

    name = 'Ray';

    var john = {
          name: 'John',
          greet: function(person) {
                alert("Hi " + person + ", my name is " + this.name);
          }
    };

    var doe = {
          name: 'Doe',
          fx: john.greet
    };

    doe.fx("Mark"); 
    Copy & paste the code below to embed this comment.
  37. Awesome article. JavaScript binding is something that I’ve only partially understood… just enough to know to try adding a Prototype bind() to any function calls that don’t work and see if that fixes it.

    After reading this article, it all makes sense finally! Thank you!

    Copy & paste the code below to embed this comment.
  38. I apologize for insulting your post. I don’t know how I got on these comments.

    Copy & paste the code below to embed this comment.
  39. thanks for this article…I’ve readed many articles about this (even book’s capitules) and never it had been clear to me…your articles was better than all that books…

    now I’ve a question..why js do it in this way?...I think many times than seemed be a complications in a language in a future this became in advantages…like closures or metaprogramming in ruby…but this binding look very weird to me…this has any advantage?.....

    thank you again and good luck

    Copy & paste the code below to embed this comment.
  40. Sorry, commenting is closed on this article.