0

鉴于问题:

了解 let 与 var 提升

用 let 或 const 声明的变量在 ES6 中没有提升吗?

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

在我的代码中,我有:

<script>

    "use strict";

    let PageInit = null;

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

        PageInit = new IPageInit();

        doSomething();

    });

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

</script>

PageInit在全局范围内创建对doSomething().

但是,如果我这样做:

<script>

    "use strict";

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

        var PageInit = new IPageInit();

        doSomething();

    });

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

</script>

我不正确理解吊装。我希望var PageInit块范围内会被提升到全局范围内,首先是<script>标签内。

但事实并非如此。

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

4

4 回答 4

1
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
}
*/

这并不意味着在函数内部声明的变量在函数外部可用。这就是函数PageInitdoSomething给出参考错误的原因。您必须在函数外部初始化变量才能不会出现此错误

于 2020-03-20T18:28:08.023 回答
1

JavaScript 中的作用域

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

JavaScript 中有两种类型的作用域。

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

全球范围

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

本地范围

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

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

结论

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

于 2020-03-20T18:41:00.317 回答
1

我很难弄清楚你在剧本中的意图是什么。但是,无论如何....

不,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 
}

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

我希望我至少对你有所帮助。

于 2020-03-20T18:41:20.120 回答
0

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

这永远不会发生。

托管影响变量何时出现,而不是where

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

    PageInit = new IPageInit();

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

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

    var PageInit = new IPageInit();

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

提升了……但由于它是函数的第一行,因此没有实际区别。

于 2020-03-20T18:28:45.437 回答