繁体   English   中英

LET 与 VAR 以及从块范围到全局范围的提升

[英]LET vs VAR and Hoisting from Block Scope to Global Scope

根据问题:

理解 let 与 var 提升

ES6 中是否未提升使用 let 或 const 声明的变量?

我不明白当提升将变量从块范围提升到全局范围时会发生什么。

在我的代码中,我有:

<script>

    "use strict";

    let PageInit = null;

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

        PageInit = new IPageInit();

        doSomething();

    });

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

</script>

在全局范围内创建的PageInitdoSomething()可见。

但是,如果我这样做:

<script>

    "use strict";

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

        var PageInit = new IPageInit();

        doSomething();

    });

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

</script>

我不理解正确吊装。 我希望块作用域内的var PageInit会被提升到全局作用域中,首先是<script>标记内的东西。

但事实并非如此。

谁能解释为什么不呢? 或者它被吊到哪里?

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

    var PageInit = new IPageInit();

    doSomething();

});

var有一个功能范围。 这意味着无论您在函数中的何处声明变量,它都可用于整个函数。

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

这并不意味着在函数内部声明的变量在函数外部可用。 这就是为什么doSomething函数中的PageInit给出引用错误的原因。 您必须在函数外部初始化变量才能不会出现此错误

JavaScript 中的作用域

JavaScript 中的作用域定义了变量、对象和函数的可访问性。

JavaScript 中有两种作用域。

  1. 全球范围
  2. 本地范围

全球范围

在任何函数之外声明的变量成为全局变量。 可以从任何函数访问和修改全局变量。

本地范围

在任何带有 var 关键字的函数中声明的变量称为局部变量。 不能在函数声明之外访问或修改局部变量。

我们都知道let是块作用域, var是它的当前执行上下文。

结论

在您的第一个示例中, let可以访问,因为它的范围是全局的,并且他在主块中。 在你的第二个例子中, var在它的本地范围内,这就是为什么它无法输出它的值

我无法弄清楚您在脚本中的意图。 然而,无论如何......

不, var在其“通用范围”内有效,因此“在其功能和子功能树中”。 所以你找不到它,因为你正在实例化一个新的情况,如果没有在参数之间传递 var 将会丢失。

如果使用let则更糟,因为它仅在该函数内有效,并且如果不作为参数传递则不会访问子函数。

在所有这些中,您正在对事件系统进行操作……事件类似于 ajax(仅在瞬间创建并丢失该事件)。 很难通过提取数据而不将它们保存在某处或将其从函数传递给另一个函数来处理它们。

它有助于理解: https : //dev.to/sarah_chima/var-let-and-const--whats-the-difference-69e

更正确的版本是这样的:

简单的想法(我没有测试过,但逻辑是这样)

var XXX;

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

    XXX = new IPageInit();

    doSomething(XXX);

}, false); 

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

所以... xxx 传递到成功的事件 => 并传递了 doSomethig。

或者...

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 
}

所以......在事件=>得到或做你所拥有的。 如果什么都没有……得到。

我希望我至少对你有用。

我不明白当提升将变量从块范围提升到全局范围时会发生什么。

这永远不会发生。

托管影响变量何时存在,而不是where

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

这隐含地声明了一个全局变量。 它不是托管的。 在函数运行之前,变量不存在。 在此之前尝试读取变量将导致异常。

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

var在其内部声明的函数范围内声明了一个变量。 所以它不会创建一个全局。

提升了……但因为它是函数中的第一行,所以没有实际区别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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