DISQUS

Caffeinated Simpleton: An Introduction to JavaScript’s “this”

  • Nik · 3 months ago
    // Call the getCondiments function in 30 seconds
    setTimeout(30, myHotDog.getCondiments);


    Where do you get that strange setTimeout? To call myHotDog.getCondiments in 30 seconds, this is the way to go:

    setTimeout(myHotDog.getCondiments, 30 * 1000);
  • justin · 3 months ago
    You're right about the order, it's been corrected. I don't really believe in putting millisecond timeouts in examples since it's needlessly detail oriented.
  • MSpreij · 3 months ago
    You still have to fix it in the first example (under "this Gets Tricky").
    Also, the following works just fine for me, in various browsers (IE7/8, FF)? No errors on the console and it happily alerts after 3 seconds.

    function HotDog() {
    this.condiments = "mustard, ketchup";
    this.getCondiments = function() {
    alert(1);
    return this.condiments;
    }
    }

    var myHotDog = new HotDog();

    setTimeout(myHotDog.getCondiments, 3000);
  • mspreij · 3 months ago
    Ok, I was wrong :-) when doing alert(this.condiments) instead it says "undefined". Now I also see why setting var me = this; helps.
  • budda · 3 months ago
    It will work if you call it once in a function-block.
    The scope of the timeout-callback will be the same as where it was called.
    try this:
    for(var i=0;i<3;i++)
    {
    setTimeout(alert(i), 500); //Will write 3, 3 times because i is 3 when alert is called
    }

    vs

    for(var i=0;i<3;i++)
    {
    var a = i;
    setTimeout(a, 500); //Will write 0, 1, 2 because a is only within the scope of the current iteration
    }


    Google closures for more info
  • Olivier MenguĂ© · 3 months ago
    Variable scope in JavaScript is function. There is no block scope.
    Defining variable 'a' with a 'var' statement inside the loop is just misleading. JavaScript is not Java.
    So the two version do the same.

    Also you didn't test your code at all.. Else you would have seen that alert is not called by setTimeOut but instead inside the loop.
    You should have written this:
    setTimeout(function { alert(i) }, 500);
  • justin · 3 months ago
    Updated the first example. Thanks!
  • Lachlan · 3 months ago
    Using:

    var my = this;

    Is such a beautiful fix, I'm amazed by its simplicity. Cheers!
  • DossyDomo · 3 months ago
    Oh wow, that actually makes sense to me dude, I like it!

    RT
    www.total-privacy.net.tc
  • DougBTX · 3 months ago
    In the "solving our setTimeout problem" code sample, why do you use apply? At this point you have a reference to the object, so you can call myHotDog.getCondiments() directly.
  • justin · 3 months ago
    You're right that it's unnecessary. I was trying to combine the previous point, but it might just make things more confusing. I might change it.
  • justin · 3 months ago
    Yeah, I think you're right DougBTX. I've changed it.
  • Jeffrey04 · 3 months ago
    i used methods introduced in http://odetocode.com/Blogs/scott/archive/2007/0... to solve 'this' problems
  • seanja · 3 months ago
    As was pointed out to me on Stackoverflow.com, you can also solve it by using closures http://stackoverflow.com/questions/1466875/ies-...
  • Marcos · 3 months ago
    All that stuff looks like PHP. Disgusting language JavaScript, ughhh...
  • hugobryn · 3 months ago
    There is a bit more to the setTimeout() function to be totally clear:

    1) setTimeout(myObj.myFunc, 1000) - this set to global window object

    2) setTimeout(function() { myObj.myFunc() }, 1000) - this set to myObj as we want it.

    But you can also pass a string to setTimeout and basically setTimeout() becomes a sort of eval:

    3) setTimeout('myObj.myFunc()', 1000) - this set to myObj

    Number 2 is the best way to go though.
  • vilcans · 3 months ago
    Good article. I have been very confused by "this".