Search code examples
javascriptarrow-functions

Arrow functions in closures


Why this is working:

var a = () => { 

    var print = function(i) { console.log(i); return this; }    
    var print2 = function(i) { console.log(i); return this; }

    return { print:print , print2:print2 }
}

a().print(5).print2(5);

this is also working:

var b = () => { 

    var print = (i) => { console.log(i); return this; }    
    return { print:print}
}
b().print('Arrow function works');

while this is not working:

var b = () => { 

    var print = (i) => { console.log(i); return this; }    
    var print2 = function(i) { console.log(i); return this; }

    return { print:print , print2:print2 }
}
b().print(5).print2(5);

https://jsfiddle.net/Imabot/1gt2kxfh/14/


Solution

  • It's all due to arrow functions behavior(docs)

    Step by step explanation:

    var b = () => { 
        // 1
        var print = (i) => { console.log(i); return this; }    
        var print2 = function(i) { console.log(i); return this; }
    
        return { print:print , print2:print2 }
    }
    const res = b()
    // 2
    const secondRes = res.print(5)
    // 3
    secondRes.print2(5);

    1. here print function saves this reference from the outer scope, so this can't be reassigned anymore
    2. now print function is not using this reference that comes from res variable, because this has already been attached to print function above
    3. as a result secondRes is not going to reference to the object that was returned by b function. But it will use this reference that is attached to print function. And finally because secondRes doesn't have print2 property - it throws