国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ReferenceError: Cannot access 'X' before

Elle / 5055人閱讀

摘要:中文文檔中的變量提升,是指在聲明變量的代碼執行之前,可以進行初始化和使用而不是指在創建詞法環境階段是否會創建對應的標識符。

問題背景

今天在 chrome devtools 中運行以下代碼:

function fn (name){
  if (typeof name === "undefined"){
     console.log("name:", name)
     let name = "lily"
  }
}
fn()

原以為可以正常 work,實際報錯:

ReferenceError: Cannot access "name" before initialization
尋找答案

閱讀 mdn let 文檔,找到以下說明:

在 ECMAScript 2015 中,let 綁定不受變量提升的約束,這意味著 let  聲明不會被提升到當前執行上下文的頂部。在塊中的變量初始化之前,引用它將會導致 ReferenceError(而使用 var 聲明變量則恰恰相反,該變量的值是 undefined )。這個變量處于從塊開始到 let 初始化處理的”暫存死區“之中。

看完上面的說明,我一臉懵逼。因為以下代碼可以正常運行:

function fn (name){
  if (typeof name === "undefined"){
     console.log("name:", name)
     // let name = "lily"
  }
}
fn() // name: undefined

也就是說,被注釋掉的第四行代碼對第三行是產生的影響的,既然 let 聲明不會被提升,那第四行代碼是怎么影響到第三行的?
思考這個問題,我想到<>中第5章中有對創建詞法環境步驟的描述,在page112中,有如下說法:

在塊級環境中,僅查找當前塊中通過 let 或 const 定義的變量。對于所查找到的變量。若該標識符不存在,進行注冊并將其初始化為undefined。若該標識符已經存在,將保留其值。

好嘛,我更懵逼了。這個意思是 let 聲明在塊作用域中會被提升吧?實踐是檢驗真理的唯一標準,在 chrome 中代碼測試下:

console.log("name:", name)
let name = "lily"

結果報錯:

ReferenceError: Cannot access "name" before initialization

這個實踐無法明確說明 let 聲明是否會提升的問題。我的唯一標準失效了。正當我束手無策時,突然考慮到翻譯過程的誤差,抱著試試看的心態查看了 mdn 文檔英文版,說明如下:

let bindings are created at the top of the (block) scope containing the declaration, commonly referred to as "hoisting". Unlike variables declared with var, which will start with the value undefined, let variables are not initialized until their definition is evaluated. Accessing the variable before the initialization results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.

這就很清晰了。原文說的是:通過 var 聲明的變量有初始值 undefined,而通過 let 聲明的變量直到定義的代碼被執行時才會初始化。在變量初始化前訪問變量會導致 ReferenceError。

總結

在上面的文檔中,其實我一直誤解了中文 javascript 文檔中對變量提升的定義。
中文 javascript 文檔中的變量提升,是指:在聲明變量的代碼執行之前,可以進行初始化和使用;而不是指:在創建詞法環境階段是否會創建對應的標識符。
通過 var 聲明的變量和 let 或 const 聲明的變量,在創建相應作用域的詞法環境階段,都會注冊標識符,但僅通過 var 聲明的變量存在會變量提升,若在通過 let 或 const 聲明了變量的(塊)作用域中,先使用再聲明該變量,就會拋出錯誤:

ReferenceError: Cannot access "X" before initialization
補充

不要過度依賴翻譯后的文檔,已更新 mdn 上這部分的中文文檔。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104262.html

相關文章

  • [譯]Understanding javascript&#039;s &#039;undefined

    摘要:一個表示編譯器檢測到一個無效的引用值。在實際情況中,往往是在獲取一個未被賦值的引用時被拋出。任何一個函數上下文都有一個被稱為活動對象的變量對象。沒有找到的話,就會認為引用名沒有基礎值并拋出的錯誤。下沒有下的屬性僅存在于被啟動的情況下。 和其他語言相比,javascript中的對于undefined的理解還是有點讓人困惑的。特別是試著理解ReferenceErrors錯誤(x is no...

    galaxy_robot 評論0 收藏0
  • Useful APIs that you probably don&#039;t notice

    摘要:結果 Date Get the number of days in a month The 0th day of next month is the last day of the current month. function daysInMonth(year, month) { let date = new Date(year, month + 1, 0); ret...

    崔曉明 評論0 收藏0
  • local variable &#039;var1&#039; referenced before

    摘要:起初是群里一個哥們這句話報錯。我竟然沒看懂代碼如下其實這個代碼不能很好的反應問題。來看以下兩個我一開始沒理解這個問題。看到和粗略的理解成不能夠在閉包函數中改變上層函數的變量。實際上是,如果一個變量被賦值,那么會認為其為局部變量。 起初是群里一個哥們這句話報錯。后來之前的一個實習生,給出了鏈接來解釋這個問題。 我竟然沒看懂.... http://stackoverflow.com/que...

    Aklman 評論0 收藏0
  • antd報錯Cannot read property &#039;filter&#039; of u

    摘要:技術棧問題描述在狀態組件中書寫下的其中涉及點擊某處出現彈框的操作,在中有選框,點擊取消或清空所有表單信息。點擊選框內的各個選項,報錯。在點擊取消之后,清空的是所有組件的內容,再打開新的彈窗后,組件的狀態并沒有刷新。 技術棧: react + dva + antd 問題描述: 在狀態組件中書寫state下的columns,其中涉及點擊某處出現彈框modal的操作,在modal中有sel...

    Tychio 評論0 收藏0
  • webpack編譯報錯Cannot find module &#039;@babel/core�

    摘要:編譯報錯用了這個指令后報錯嘗試重新下載了還是不行原來是被我更新了不支持原來的配置了,官方默認對應的版本需要一致即需要搭配最新版本兩種解決方案回退低版本更新到最高版本編譯無法識別語法需要安裝之后 ** webpack編譯報錯Cannot find module @babel/core **~ npm install babel-core babel-loader --save-dev ...

    DandJ 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<