成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ReferenceError: Cannot access 'X' before

Elle / 5069人閱讀

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

問題背景

今天在 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  聲明不會被提升到當前執(zhí)行上下文的頂部。在塊中的變量初始化之前,引用它將會導致 ReferenceError(而使用 var 聲明變量則恰恰相反,該變量的值是 undefined )。這個變量處于從塊開始到 let 初始化處理的”暫存死區(qū)“之中。

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

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

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

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

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

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

結(jié)果報錯:

ReferenceError: Cannot access "name" before initialization

這個實踐無法明確說明 let 聲明是否會提升的問題。我的唯一標準失效了。正當我束手無策時,突然考慮到翻譯過程的誤差,抱著試試看的心態(tài)查看了 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 聲明的變量直到定義的代碼被執(zhí)行時才會初始化。在變量初始化前訪問變量會導致 ReferenceError。

總結(jié)

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

ReferenceError: Cannot access "X" before initialization
補充

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

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/104262.html

相關文章

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

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

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

    摘要:結(jié)果 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

    摘要:起初是群里一個哥們這句話報錯。我竟然沒看懂代碼如下其實這個代碼不能很好的反應問題。來看以下兩個我一開始沒理解這個問題??吹胶痛致缘睦斫獬刹荒軌蛟陂]包函數(shù)中改變上層函數(shù)的變量。實際上是,如果一個變量被賦值,那么會認為其為局部變量。 起初是群里一個哥們這句話報錯。后來之前的一個實習生,給出了鏈接來解釋這個問題。 我竟然沒看懂.... http://stackoverflow.com/que...

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

    摘要:技術(shù)棧問題描述在狀態(tài)組件中書寫下的其中涉及點擊某處出現(xiàn)彈框的操作,在中有選框,點擊取消或清空所有表單信息。點擊選框內(nèi)的各個選項,報錯。在點擊取消之后,清空的是所有組件的內(nèi)容,再打開新的彈窗后,組件的狀態(tài)并沒有刷新。 技術(shù)棧: react + dva + antd 問題描述: 在狀態(tài)組件中書寫state下的columns,其中涉及點擊某處出現(xiàn)彈框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

發(fā)表評論

0條評論

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