首頁  >  文章  >  web前端  >  一起聊聊JavaScript中的聲明提升

一起聊聊JavaScript中的聲明提升

WBOY
WBOY轉載
2022-11-14 17:59:021165瀏覽

這篇文章為大家帶來了關於JavaScript的相關知識,其中主要介紹了關於宣告提升的相關內容,宣告提升是JavaScript解析器的一個特性,會對程式碼中的函數、變數宣告語句作用提取到它所在的作用域的最前面,下面一起來看一下,希望對大家有幫助。

一起聊聊JavaScript中的聲明提升

【相關推薦:JavaScript影片教學web前端

聲明提升(hosting)是JavaScript 解析器的一個特性,它會把程式碼中的函數、變數宣告語句作用提取到它所在作用域的最前面。

函數的提升

JavaScript 是支援在函數宣告之前呼叫函數的。

say();function say() {  console.log("Hello");
}

解析器會掃描作用域內的程式碼,把函數宣告提取到執行程式碼的前面。所以,解析器是這樣看這段程式碼的:

function say() {  console.log("Hello");
}say();

除了普通函數,async function, function *, async function *也有相同的提升效果。

var 變數宣告提升

var 關鍵字的變數宣告會被提升,但變數的賦值不會被提升。

console.log(foo); // undefinedvar foo = "bar";console.log(foo); // 'bar'

以上程式碼的解析結果為:

var foo;console.log(foo);
foo = "bar";console.log(foo);

這可能會導致一些奇怪的問題:

var x = "x in global";

(function () {  // 这里期望读取全局变量
  console.log(x); // 结果为undefined. 
  /* ... */
  // 在函数内某处
  var x = "x in function";
})();

在過去,為了規避這種奇怪的提升,大家普遍把var 宣告寫在作用域的最前面。

var x='x';var y='y';function (){    var x;    var foo;    // ...}

當然,現在我們選擇不用 var,改用更合理的 letconst

letconst 變數宣告和死區

那麼,letconst 就不存在變數提升了嗎? —— 未必。

看這個例子:

const x = "x in global";

(function () {  // 这里期望读取全局变量
  console.log(x); // ReferenceError: Cannot access 'x' before initialization
  /* ... */
  // 在函数内某处
  const x = "x in function";
})();

執行報錯,說明 const x = "x in function"; 一行影響了作用域內的上方區域代碼。

解析器會掃描目前作用域下的 constlet 聲明,在宣告語句之前使用變數名稱都會觸發 ReferenceError。這樣可以避免上面提過的 var 提升問題和模糊的程式碼範式。

class 關鍵字也有相同的效果,new 一個未宣告的類別也會發生 ReferenceError

new MyClass(); // ReferenceError: Cannot access 'MyClass' before initializationclass MyClass {}

有人認為這種情況不屬於提升,畢竟聲明和賦值都沒有提前;也有人認為這些語句在執行之前就產生了影響,其作用提升了。個人偏向後者,這是對(變數和類別名稱)標識符的提升。

總結

某些 JavaScript 宣告語句的效果會影響到所在的整個作用域,這種現象稱為提升。

有 3 種類型的提升:

  • function 關鍵字的宣告和賦值都會提升。
  • var 關鍵字宣告提升,賦值不提升。
  • let, const, class 識別碼提升,形成死區,宣告和賦值都不提升。

【相關推薦:JavaScript影片教學web前端

以上是一起聊聊JavaScript中的聲明提升的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除