3

I'm using the new ES6 Classes and am having a hard time understanding why I can reference the this variable is one of the methods.

//CLASS

class Form{ 
    constructor(){
        var self = this;
    }   

    assemble(){
        log(self);
    }
}

//CALLED

var form = new Form();
form.assemble();

//RETURN

window object (not the reference to the class object)
  • Possible duplicate of [using the 'this' variable within object constructor](http://stackoverflow.com/questions/40515218/using-the-this-variable-within-object-constructor) –  Nov 28 '16 at 18:29
  • Possible duplicate: [How does the “this” keyword in Javascript act within an object literal?](http://stackoverflow.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object-literal/13441628#13441628) – Igor Nov 28 '16 at 18:29
  • 3
    self is an actual, existing property on window: https://developer.mozilla.org/en-US/docs/Web/API/Window/self You are redefining it in your constructor as a local variable, temporarily, and then doing nothing with it. In your assemble() method, you are NOT actually referencing that self variable you declared in your constructor, you are referencing window.self. – Jeff McCloud Nov 28 '16 at 18:32

1 Answers1

3

this isn't a variable. It's more like a hidden argument to functions.

You can't access self in your example because it's a local variable within the constructor, so it's not available to your assemble method.

You don't need self at all for your example, just use this:

class Form {
    assemble(){
        log(this);             // ***
    }
}
var form = new Form();
form.assemble();

If you were passing form.assemble to something that wouldn't guarantee to call it with the right this, you could define assemble as an instance function member instead, by defining it in the constructor; then it would close over self. But you don't need self for this in ES2015 and above; just use an arrow function, which closes over this:

class Form {
    constructor(){
        var self = this;
        this.assemble = () => {
            log(this);
        };
    }   
}
var form = new Form();
form.assemble();          // Works
var f = form.assemble;
f();                      // Also works

But odds are you don't need to do that.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thank you! so simple, just not use to it stuck in my old ways, haha. –  Nov 28 '16 at 18:32
  • Does defining the function in the constructor have any advantages over defining it as a normal class function and binding it in the constructor, i.e. `this.foo = this.foo.bind(this)`? I personally find the latter to be more readable. – TimoStaudinger Nov 28 '16 at 18:35
  • 2
    @Timo: If you use an arrow function like I did above, no, no technical advantage either way, just the style difference. I mean, okay, technically with the `bind` solution there's an extra function (just the one, not one per instance), but who cares? If you use a `function` function in the constructor instead of an arrow (but why would you? :-) ), then the `bind` solution is better, because you can use `super` in that case but can't from a `function` function created in the constructor. – T.J. Crowder Nov 28 '16 at 18:42
  • @T.J.Crowder Thanks for the clarification! – TimoStaudinger Nov 28 '16 at 18:43