Hacker News new | ask | show | jobs
by mambodog 4209 days ago
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.