Search code examples
javascriptscopethis

Why can't I access a declared variable in the global scope


        var bar = {
            myName: 'bar',
            printName: function () {
                console.log(this.myName)
            }
        }
        function foo() {
            let myName = 'foo'
            return bar.printName
        }
        let myName = 'outer'
        let _printName = foo()
        _printName()
        bar.printName()

Why the result of the first function execution is undefined ? I thought the result would be 'outer', and why output 'outer' after changing let to var ? This is so confusing, please help me.


Solution

  • Why the result of the first function execution is undefined ?

    Because you don't bind this to anything in the function call (you neither have objectThatWillBecomeThis.printName() nor printName.call(objectThatWillBecomeThis)). In strict mode, this would crash because this would be undefined then and you'd try to read undefined.myName. But since you didn't enable strict mode, the legacy behavior is active in which this - when not explicitly set - will be set to the global object. However, the global object doesn't have any property myName (in the browser: there is no window.myName) so the result is undefined.

    why output 'outer' after changing let to var ?

    Because if you run this code in the global scope, var outside of any other scope will create a property on the global object (window.myName). let doesn't do that:

    At the top level of programs and functions, let, unlike var, does not create a property on the global object. For example:

    var x = 'global';
    let y = 'global';
    console.log(this.x); // "global"
    console.log(this.y); // undefined
    

    If you'd move the code inside a function, it wouldn't work either, by the way, because the var (or let, doesn't matter now) statement would just create a local variable in the function and not a property on the global object, so there would be no way to access it through any object's myName property.