HN2new | past | comments | ask | show | jobs | submitlogin

var self = this; why do people bother with 'this'?


because you sometimes want to refer to the original 'this' reference inside an inner nested function scope, where the actual 'this' keyword is rebound to the context of the inner function.

    function outer() {
        var outer_this = this;
        var inner = function() {
            var inner_this = this;
            // ...
        }
    }
http://stackoverflow.com/questions/4886632/what-does-var-tha... has some more details.


Of course there are exceptions to the rule, but the rule should still be - avoid 'this.'


IMO the use of self as the name of the variable referencing to 'this' is a little dangerous, because in a function, if you miss the line var self = this, self is a valid reference to the window object, so you will not get an expected error for an undefined variable.


Better a little dangerous 'self' than a lot of dangerous 'this.'


There's no real danger difference. If you implicitly do:

    var self = this;
When you need to use `this`, you just end up proxying the problem behind a variable. If you don't understand what `this` is, it's not going to magically start correcting your misunderstanding.

The only possible value it might have is when nesting functions if you refer to `self` instead of `this` correctly, but this is the only case when I actually use this pattern, and when I first create a nested function that needs to use the parent's scope. Another option is to just `.bind(this)`.

In any case, I would disagree that one should try to avoid `this`. Instead, one should educate themselves to understand what things in the language they're using mean. And this subject is a great weeder question in Web Engineer position interviews. If a person can't implement `bind`, can't explain `call`/`apply`, what strict mode does, and what the `this` keyword means in most contexts, they probably aren't strong enough in JS. This is one of the most fundamental concepts in JS, it shouldn't be a source of confusion.


I understand 'this', that's why I avoid it. All languages have their quirks, and some programmers like to think they're 'smart' by taking advantage of those quirks. Then when you or your team members run into problems you blame the person and not the language, which you're right, but maybe you should of just kept your code simple in the first place.


I'm not sure I understand you.

Dereferencing things that aren't pointers leads to unexpected results in C. Should we avoid dereferencing any variable in C?

I think of `this` in the same way - it behaves normally if you use it the way it's intended to be used. In other words, don't try to read `this` in a callback without binding it first, and you'll be fine.

Or are there other pitfalls I'm unaware of?


Totally, just remember to use var. Dangerous this is much scary then accidentally adding a global variable.


The problem with `self` is that it is already a predefined global variable in the browser pointing to the global object :)

And btw, the `this` situation with javascript is not that bad :) use bind - either the Ecmascript 5 version or shimmed and you will be fine. Not much drama.


Well you might just use some other name than `self` e.g. I use var _this = this;


how about var that = this;


I'm confused... doesn't that just reduce the question to "what is the current binding of self"?


After assignment "self" does not change even if "this" does.

    var player = { 
        play: function(){
            var self = this;
            setTimeout(function(){
                console.log(self);
            });
        }
    }


No but this is still bound at call time, so `self` will be foo in foo.play() just as this, so that's basically the same thing + a standard variable assignment to get the setTimeout working.

On a sidenote, I'm trying to get away from using self, and do object.bind in all my setTimeouts. To my mind, it leads to much cleaner code.


object.bind doesn't look very clean compared to using self.


The nice thing about it is that it allows you to break out of nesting hell while still being prototyped... e.g. window.setTimeout(this.foo.bind(this), baz);

Since .bind is essentially currying, you could imaginably do window.setTimeout(this.foo.bind(this, bar), baz) as well, if foo is dependent on bar (timing out a request `bar' or something like that).


And in JS is really easy to create an abstraction for this issue:

    function wait(o){
      return setTimeout(function(){ o.action.call(o.this) },o.delay*1000)
    }    
To use it like this:

    wait({
       action : function(){ console.log(this) },
       delay : 1,       
       this : this
    });


If you're writing abstractions to avoid bad language features, maybe you shouldn't be using bad language features in the first place.


Bind is not supported in IE8 and older versions. You could use the underscore library or another one that haves a cross-browser bind method.


For my particular use case, IE8 is not an issue, but sure, a shim is like three lines, and we did use that before (when IE8 was an issue).


But you still have to be aware of the semantics of `this`:

    var play = player.play;
    play();
"self" will still strangely bind to "window" if not in strict mode.


Of course, taking the method out of the object will produce a different result. But if you are doing something weird like that you should know what you are doing.


I don't think it's _that_ weid considering JS is a language where functions are perfectly normal values. Someone unfamiliar with the semantics of "this" in JS might expect that:

    player[playing ? "play" : "pause"]()
(a not-so-weird JS pattern) would be the same as:

    (playing ? player.play : player.pause)()


Indeed --- Python goes to great lengths to work this way, automatically binding the self argument on method extraction.

    o.f()
Can be decomposed in Python:

    func = o.f
    func()
JavaScript fails this test, and it's a shame.


Ho, you beat me to it with the Python reference (see my other comment in this thread) :)

I don't know if it's really that bad that JS returns the unbound function when doing `obj.someFunc`, as it is consistent with any other property access: it returns the same thing that was assigned to that key in the object, or at some point in its prototype chain.

The really broken behavior, at least for me, is that when doing `var f = obj.someFunc(); f()`, the "this" gets bound to "window" in the f() call, instead of being null, or better yet raising an error whenever referenced, like an undefined variable.


It's actually a Javascript strength; one that makes it more dynamic.

    NodeList.prototype.map = Array.prototype.map
Just one line and now you can do stuff like:

    document.querySelectorAll("div").map(function(ele){
      return ele.id
    });


In what other language you have direct access to methods as first class objects to do an immediate execution of a method returned by an execution container (parenthesis in JS) ?

I think most people would write it like this:

    playing ? player.play() : player.pause()


> In what other language you have direct access to methods as first class objects to do an immediate execution of a method returned by an execution container (parenthesis in JS) ?

Not sure if i understand the question. This seems to work in Python:

    s = "Hello"
    up = True
    (s.upper if up else s.lower)()
Not that it's a very pythonic piece of code, but it works, and i would expect many other languages support something similar.

Anyway, that's tangential. And i wasn't discussion what "most people would" do either. What i was trying to say is that by aliasing "var self = this" you're not automatically immune to the quirks of "this" in JS.


For consistency and to avoid populating the scope with named variables, look at how jQuery works for good examples of how to use 'this' (the puns are infinite with this)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: