中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS作用域的陷阱有哪些

發布時間:2020-12-28 09:45:47 來源:億速云 閱讀:151 作者:小新 欄目:web開發

這篇文章給大家分享的是有關JS作用域的陷阱有哪些的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

在 JavaScript 中,代碼塊、函數或模塊為變量創建作用域。例如 if 代碼塊為變量 message 創建作用域:

if (true) {
  const message = 'Hello';
  console.log(message); // 'Hello'
}
console.log(message); // throws ReferenceError

if 代碼塊作用域內可以訪問 message。但是在作用域之外,該變量不可訪問。

好的,這是作用域的簡短介紹。如果你想了解更多信息,建議閱讀我的文章用簡單的詞解釋 JavaScript 作用域。

以下是 5 種有趣的情況,其中 JavaScript 作用域的行為與你預期的不同。你可能會研究這些案例以提高對作用域的了解,或者只是為面試做準備。

1. for 循環內的 var 變量

思考以下代碼片段:

const colors = ['red', 'blue', 'white'];

for (let i = 0, var l = colors.length; i < l; i++) {
  console.log(colors[i]); // 'red', 'blue', 'white'
}
console.log(l); // ???
console.log(i); // ???

當你打印 li 變量時會發生什么?

答案

console.log(l) 輸出數字 3 ,而 console.log(i) 則拋出 ReferenceError

l 變量是使用 var 語句聲明的。你可能已經知道,var 變量僅受函數體作用域限制而并非代碼塊。

相反,變量 i 使用 let 語句聲明。因為 let 變量是塊作用域的,所以 i 僅在 for 循環作用域內才可訪問。

修復

l 聲明從 var l = colors.length 改為 const l = colors.length。現在變量 l 被封裝在 for 循環體內。

2. 代碼塊中的函數聲明

在以下代碼段中:

// ES2015 env
{
  function hello() {
    return 'Hello!';
  }
}

hello(); // ???

調用 hello() 會怎樣? (代碼段在 ES2015 環境中執行)

答案

因為代碼塊為函數聲明創建了作用域,所以在 ES2015 環境中調用 hello() 會引發  ReferenceError: hello is not defined

有趣的是,在 ES2015 之前的環境中,在執行上述代碼段時不會拋出錯誤。 你知道為什么嗎?請在下面的評論中寫下你的答案!

3. 你可以在哪里導入模塊?

你可以在代碼塊中導入模塊嗎?

if (true) {
  import { myFunc } from 'myModule'; // ???
  myFunc();
}
答案

上面的腳本將觸發錯誤: 'import' and 'export' may only appear at the top-level

你只能在模塊文件的最頂級作用域(也稱為模塊作用域)中導入模塊。

修復

始終從模塊作用域導入模塊。另外一個好的做法是將 import 語句放在源文件的開頭:

import { myFunc } from 'myModule';

if (true) {
  myFunc();
}

ES2015 的模塊系統是靜態的。通過分析 JavaScript 源代碼而不是執行代碼來確定模塊的依賴關系。所以在代碼塊或函數中不能包含 import 語句,因為它們是在運行時執行的。

4. 函數參數作用域

思考以下函數:

let p = 1;

function myFunc(p = p + 1) {
  return p;
}

myFunc(); // ???

調用 myFunc() 會發生什么?

答案

當調用函數 myFunc() 時,將會引發錯誤: ReferenceError: Cannot access 'p' before initialization

發生這種情況是因為函數的參數具有自己的作用域(與函數作用域分開)。參數 p = p + 1 等效于 let p = p + 1

讓我們仔細看看 p = p + 1

首先,定義變量 p。然后 JavaScript 嘗試評估默認值表達式 p + 1,但此時綁定  p  已經創建但尚未初始化(不能訪問外部作用域的變量  let p = 1)。因此拋出一個錯誤,即在初始化之前訪問了 p

修復

為了解決這個問題,你可以重命名變量 let p = 1 ,也可以重命名功能參數 p = p + 1

讓我們選擇重命名函數參數:

let p = 1;

function myFunc(q = p + 1) {
  return q;
}

myFunc(); // => 2

函數參數從 p 重命名為 q。當調用 myFunc() 時,未指定參數,因此將參數 q 初始化為默認值 p + 1。為了評估 p +1,訪問外部作用域的變量 pp +1 = 1 + 1 = 2

5. 函數聲明與類聲明

以下代碼在代碼塊內定義了一個函數和一個類:

if (true) {
  function greet() {
    // function body
  }

  class Greeter {
    // class body
  }
}

greet();       // ???
new Greeter(); // ???

是否可以在塊作用域之外訪問 greetGreeter(考慮 ES2015 環境)

答案

functionclass 聲明都是塊作用域的。所以在代碼塊作用域外調用函數 greet() 和構造函數 new Greeter() 就會拋出 ReferenceError

6. 總結

必須注意 var 變量,因為它們是函數作用域的,即使是在代碼塊中定義的。

由于 ES2015 模塊系統是靜態的,因此你必須在模塊作用域內使用 import 語法(以及 export)。

函數參數具有其作用域。設置默認參數值時,請確保默認表達式內的變量已經用值初始化。

在 ES2015 運行時環境中,函數和類聲明是塊作用域的。但是在 ES2015 之前的環境中,函數聲明僅在函數作用域內。

感謝各位的閱讀!關于“JS作用域的陷阱有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

尉犁县| 祁东县| 龙井市| 旺苍县| 枣阳市| 旌德县| 宁南县| 邢台市| 衡山县| 西畴县| 扎兰屯市| 收藏| 松原市| 桐柏县| 资中县| 罗甸县| 定日县| 龙陵县| 黄龙县| 兰州市| 镇原县| 贵州省| 庆云县| 绍兴县| 闻喜县| 清徐县| 华宁县| 保靖县| 五大连池市| 富川| 宜君县| 霞浦县| 同江市| 正宁县| 池州市| 瓮安县| 大埔区| 鄱阳县| 枣阳市| 茶陵县| 祥云县|