Live data from Hacker News

“This” in JavaScript

bjorn.tipling.com

51–60 of 99 posts

Re: “This” in JavaScript

#52
post #2

Not mentioned are ES6's arrow functions that capture the `this` value of the enclosing context. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

I think the new arrow functions are neat, but am I the only one who never really found it a hassle to throw a .bind(this) on a function?

Aside from the fact that your "never" somewhat dismisses the first however many years of web development (up to IE9) when `Function.prototype.bind` couldn't universally be expected to be supported, surely having a nice piece of syntax which is both shorter than writing out `function` and serves the purpose of binding the function in the way that, a good majority of the time, you actually want it bound, is a good thing?

As someone who's spent a lot of time writing CoffeeScript, I think ES6's fat arrows are a great thing, though I have my usual concerns about their confusing the hell out of people who may well have been writing JavaScript for a long time but in environments where they don't necessarily get exposed to new and exciting stuff. But hey, that's progress, I guess.

Re: “This” in JavaScript

#53
Tony Hoare has famously described null references as his billion dollar mistake. Given how often we see articles attempting to explain `this` in JavaScript (indicative, therefore, of the general level of confusion around it), I wonder if perhaps we should be starting to think about `this` in similar terms.

Re: “This” in JavaScript

#55
Another way of thinking about it is that it's kinda like Function.prototype.call is being used implicitly at the call site to set the 'context' (the 'this' value):

    // assuming in each case
    var o = {}
    var o2 = {}
    var fn = function(){}
    
    // 1. bare function call
    fn() // this == undefined in strict mode, global in non strict mode.
    
    // 2. calling with Function.prototype.call
    fn.call(o) // this == o
    
    // 3. 'method' call (calling an object's function property)
    o2.fn = fn
    o2.fn() // this == o2
    // equivalent to
    fn.call(o2)

    // 4. calling object's function property with Function.prototype.call
    o2.fn = fn
    o2.fn.call(o) // this == o

    // 5. new
    var o3 = new fn() // this = o3
    // equivalent to
    var o3 = Object.create(fn.prototype)
    fn.call(o3)

    // 6. calling function bound with Function.prototype.bind
    var fn2 = fn.bind(o)
    fn2() // this == o
    // equivalent to
    var fn2 = function(){ fn.call(o) }
    fn2()

    // 7. calling object function property which is a bound function
    o2.fn = fn.bind(o)
    o2.fn() // this == o
    // equivalent to
    o2.fn = function(){ fn.call(o) }
    o2.fn()
    
  
Basically you should think of functions (and 'methods') as not being intrinsically bound (as in binding-of-'this' bound) to anything.

If you think of a 'method' (function property) as being bound an object purely by being 'attached' to it then you are gonna have a bad time. Instead, think of binding of 'this' as usually only happening at call time, to the thing you are 'calling the function off of'.

In reference to case 1 (bare function call), this is the same behaviour which occurs when as defining an anonymous function inside a function which has 'this' set. Just don't use 'this' in this case, it doesn't make sense. Defining a _this or self variable in the parent function is the standard practice to deal with this case, or in ES6, Coffeescript etc. you have the => fat arrow to implicitly do that for you.

Re: “This” in JavaScript

#56
post #31

The author critically misunderstands the way that `this` gets set, and in doing so has developed a significantly overcomplicated mental model. This is exemplified in the statement: You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new. ... Note, there was no use of new , no Object.create and no function called to create obj. Thi…

Even more simply, I'd just say: 1) The keyword "this" refers to whatever is left of the dot at call-time. 2) If there's nothing to the left of the dot, then "this" is the root scope (e.g. Window). 3) A few functions change the behavior of "this"— bind , call and apply 4) The keyword "new" binds this to the object just created So if you're using the value of "this" in someFunction... thing.someFunction(); // this ===…

Nice summary.

Re: “This” in JavaScript

#57
post #31

The author critically misunderstands the way that `this` gets set, and in doing so has developed a significantly overcomplicated mental model. This is exemplified in the statement: You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new. ... Note, there was no use of new , no Object.create and no function called to create obj. Thi…

Even more simply, I'd just say: 1) The keyword "this" refers to whatever is left of the dot at call-time. 2) If there's nothing to the left of the dot, then "this" is the root scope (e.g. Window). 3) A few functions change the behavior of "this"— bind , call and apply 4) The keyword "new" binds this to the object just created So if you're using the value of "this" in someFunction... thing.someFunction(); // this ===…

Exactly. Once you understand underlying concept, `this` is not complicated or weird.

Small addendum to your list: "whatever is left of the dot at call-time" is a nice way to explain "base reference" concept, but be wary of non-trivial constructs:

    (f = thing.someFunction)(); // this references global object
    (function(){return thing.someFunction }())(); // this references global object
    eval('thing.someFunction')(); // this references global object

Re: “This” in JavaScript

#58

The author critically misunderstands the way that `this` gets set, and in doing so has developed a significantly overcomplicated mental model. This is exemplified in the statement: You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new. ... Note, there was no use of new , no Object.create and no function called to create obj. Thi…

It helped me immensely when I realized

    obj.method();
is a sugar for

    obj.method.call(obj);
Similarly, this picture helped me understand `bind`:

http://i.stack.imgur.com/StZOr.png

The a-ha moment for JS is when you realize it's a way simpler language than you thought it was.

Re: “This” in JavaScript

#59
post #31

The author critically misunderstands the way that `this` gets set, and in doing so has developed a significantly overcomplicated mental model. This is exemplified in the statement: You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new. ... Note, there was no use of new , no Object.create and no function called to create obj. Thi…

Even more simply, I'd just say: 1) The keyword "this" refers to whatever is left of the dot at call-time. 2) If there's nothing to the left of the dot, then "this" is the root scope (e.g. Window). 3) A few functions change the behavior of "this"— bind , call and apply 4) The keyword "new" binds this to the object just created So if you're using the value of "this" in someFunction... thing.someFunction(); // this ===…

Very nice way to word it! But I would add that if you are using strict mode (which you should) then you get "undefined" instead of "Window" in rule 2)

Re: “This” in JavaScript

#60
post #31

The author critically misunderstands the way that `this` gets set, and in doing so has developed a significantly overcomplicated mental model. This is exemplified in the statement: You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new. ... Note, there was no use of new , no Object.create and no function called to create obj. Thi…

Even more simply, I'd just say: 1) The keyword "this" refers to whatever is left of the dot at call-time. 2) If there's nothing to the left of the dot, then "this" is the root scope (e.g. Window). 3) A few functions change the behavior of "this"— bind , call and apply 4) The keyword "new" binds this to the object just created So if you're using the value of "this" in someFunction... thing.someFunction(); // this ===…

A few more are listed here:

https://news.ycombinator.com/item?id=4986125

Post reply on HN