简体   繁体   中英

LET vs VAR and Hoisting from Block Scope to Global Scope

In light of questions:

Understanding let vs. var hoisting and

Are variables declared with let or const not hoisted in ES6?

I do not understand what happens when hoisting lifts a variable out of block scope, into global scope.

In my code, I have:

<script>

    "use strict";

    let PageInit = null;

    document.addEventListener("DOMContentLoaded", () => {

        PageInit = new IPageInit();

        doSomething();

    });

    function doSomething() {
        alert(PageInit.RefreshCounter); // 60 //correct
    }

</script>

PageInit being created in the global scope is visible to doSomething() .

However, if I do this:

<script>

    "use strict";

    document.addEventListener("DOMContentLoaded", () => {

        var PageInit = new IPageInit();

        doSomething();

    });

    function doSomething() {
        alert(PageInit.RefreshCounter); // referenceError
    }

</script>

I am not understanding hoisting properly. I expected that var PageInit inside block scope would get hoisted into global scope, first thing inside the <script> tag.

But it doesn't.

Can anyone explain why not? Or where does it get hoisted to?

document.addEventListener("DOMContentLoaded", () => {

    var PageInit = new IPageInit();

    doSomething();

});

var has a functional scope. This means no matter where you declare a variable in a function, it's available to the entire function.

 function fn () { console.log(b) var b = 10 } fn() /* this is same as writing function fn () { var b ======================> hoisted console.log(b) b = 10 } */

This doesn't mean that the variable declared inside a function would be available outside of it. And this is why PageInit in doSomething function gives reference error. You will have to initialize the variable outside the function to not get this error

Scope in JavaScript

Scope in JavaScript defines accessibility of variables, objects and functions.

There are two types of scope in JavaScript.

  1. Global Scope
  2. Local Scope

Global Scope

Variables declared outside of any function become global variables. Global variables can be accessed and modified from any function.

Local Scope

Variables declared inside any function with var keyword are called local variables. Local variables cannot be accessed or modified outside the function declaration.

We all know that let is block scope and var is it's current execution context .

Conclusion

In your first example let can be access because it's scope is global and he is in main block. In your second example var is in it's local scope that's why it is unable to output it's value

I'm having trouble figuring out what your intention is in the script. however and in any case ....

no, var is valid within its " general purpose scope " so " in the tree of its functions and subfunctions ". So you don't find it because you are instancing a new situation and that var will be lost if not passed between the parameters.

If you use let it is even worse because it is valid only within that function and does not access the sub functions if not passed as a parameter.

In all this you are acting on an event system ... events are simil to ajax (create only on moment and lost out that event). it's difficult to process them by extracting data without saving them somewhere or pass it from function to another.

it is useful for understanding: https://dev.to/sarah_chima/var-let-and-const--whats-the-difference-69e

a more correct version would be like:

simple idea (I have not tested it but the logic is that)

var XXX;

document.addEventListener("DOMContentLoaded", XXX => {

    XXX = new IPageInit();

    doSomething(XXX);

}, false); 

function doSomething(myval) {
    alert(myval); // now have XXX here 
}

So... xxx passed into success of event => and passed on doSomethig.

or...

document.addEventListener("DOMContentLoaded", () => {

    var XXX = getaval();

    doSomething(XXX);

}, false); 

function getaval() {
     return IPageInit(); // now have XXX here 
}

function doSomething(myval) {
    alert(myval); // now have XXX here 
}

So... on event => get or do what you have. if have nothing... get.

I hope I have been useful to you at least a little.

I do not understand what happens when hoisting lifts a variable out of block scope, into global scope.

This never happens.

Hosting affects when a variable comes into existence, not where .

 document.addEventListener("DOMContentLoaded", () => { PageInit = new IPageInit();

That implicitly declares a global. It isn't hosted. The variable doesn't exist until the function is run. Trying to read the variable before then will result in an exception.

 document.addEventListener("DOMContentLoaded", () => { var PageInit = new IPageInit();

var declares a variable in the scope of the function it is declared inside. So it won't create a global.

It is hoisted … but as it is the first line in the function, that makes no practical difference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM