這篇文章為大家帶來了關於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
,改用更合理的 let
和 const
。
let
和const
變數宣告和死區那麼,let
和const
就不存在變數提升了嗎? —— 未必。
看這個例子:
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";
一行影響了作用域內的上方區域代碼。
解析器會掃描目前作用域下的 const
和 let
聲明,在宣告語句之前使用變數名稱都會觸發 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中文網其他相關文章!