JavaScript中的聲明提升實例詳解
函數(shù)的提升
聲明提升(hosting)是 JavaScript 解析器的一個特性,它會把代碼中的函數(shù)、變量聲明語句作用提取到它所在作用域的最前面。
JavaScript 是支持在函數(shù)聲明之前調用函數(shù)的。
say();
function say() {
console.log("Hello");
}
解析器會掃描作用域內的代碼,把函數(shù)聲明提取到執(zhí)行代碼的前面。所以,解析器是這樣看這段代碼的:
function say() {
console.log("Hello");
}
say();
除了普通函數(shù),async function, function *, async function * 也有相同的提升效果。
var 變量聲明提升
var 關鍵字的變量聲明會被提升,但變量的賦值不會被提升。
console.log(foo); // undefined var 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. ??
/* ... */
// 在函數(shù)內某處
var x = "x in function";
})();
在過去,為了規(guī)避這種奇怪的提升,大家普遍把var 聲明寫在作用域的最前面。
var x='x';
var y='y';
function (){
var x;
var foo;
// ...
}
當然,現(xiàn)在我們選擇不用 var,改用更合理的 let 和 const。
let 和 const 變量聲明和死區(qū)
那么,let 和 const 就不存在變量提升了嗎?—— 未必。
看這個例子:
const x = "x in global";
(function () {
// 這里期望讀取全局變量
console.log(x); // ReferenceError: Cannot access 'x' before initialization
/* ... */
// 在函數(shù)內某處
const x = "x in function";
})();
執(zhí)行報錯,說明 const x = "x in function"; 一行影響了作用域內的上方區(qū)域代碼。
解析器會掃描當前作用域下的 const 和 let 聲明,在聲明語句之前使用變量名都會觸發(fā) ReferenceError。這樣可以避免上面提過的 var 提升問題和模糊不清的代碼范式。
class 關鍵字也有同樣的效果,new 一個未聲明的類也會發(fā)生 ReferenceError。
new MyClass(); // ReferenceError: Cannot access 'MyClass' before initialization
class MyClass {}
有人認為這種情況不屬于提升,畢竟聲明和賦值都沒有提前;也有人認為這些語句在執(zhí)行之前就產(chǎn)生了影響,其作用提升了。個人偏向后者,這是對(變量和類名)標識符的提升。
總結
一些 JavaScript 聲明語句的效果會影響到所在的整個作用域,這種現(xiàn)象稱為提升。
有 3 種類型的提升:
function關鍵字的聲明和賦值都提升。var關鍵字聲明提升,賦值不提升。let,const,class標識符提升,形成死區(qū),聲明和賦值都不提升。
以上就是JavaScript中的聲明提升實例詳解的詳細內容,更多關于JavaScript 聲明提升的資料請關注腳本之家其它相關文章!
相關文章
JS中使用TextDecoder解碼二進制數(shù)據(jù)(數(shù)據(jù)流的逐步解碼)
JS中使用TextDecoder將二進制數(shù)據(jù)轉換為可讀文本字符串,首先,創(chuàng)建TextDecoder對象,使用decode()方法,解碼為字符串,,{stream:true}選項允許處理流式數(shù)據(jù),適用于大型數(shù)據(jù)流的逐步解碼,TextDecoder廣泛應用于WebSocket通信、文件讀取、網(wǎng)絡響應等場景2024-10-10

