簡體   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