【作用域】變數提升
阿新 • • 發佈:2019-02-11
一、什麼是變數提升
先思考下面程式碼
console.log(a);
var a = 1;
test();
function test(){
console.log('test is running')
}
結果是
console.log(a); // undefined
var a = 1;
test(); // test is running
function test(){
console.log('test is running')
}
b=2;
變數a
和函式test
的定義在使用之後,為什麼沒有報錯呢?原因就是我們常說的變數提升
。
我們知道ES6之前沒有塊級作用域,只有全域性作用域
函式作用域
。JS在執行指令碼之前會先解析程式碼
,在解析的時候會建立一個全域性執行上下文
,並將其中的變數、函式
都先拿出來,並給它們提前在記憶體中開闢好空間,變數暫時賦值為undefined
,函式則會宣告好
,整個儲存在記憶體中,這一步做完了再正式執行程式
。函式在執行的時候同理,也會先解析程式碼,建立一個函式執行上下文
,將其中的變數、函式
提前準備好。
所以,當執行console.log(a)
的時候,JS解析器已經提前把a定義好並賦值為undefined。可以在函式定義前就呼叫。
二、變數提升的幾點注意事項
1.不帶var
修飾符的變數不會提升
console.log(a); // Uncaught ReferenceError: a is not defined
a = 1;
JS在解析變數時會查詢var關鍵字
,如果變數沒有通過var來定義,則不能提前定義。
2.函式名和變數名相同時,函式會覆蓋變數
// 先定義變數再定義函式的時候
console.log(typeof a); // function
var a = 1;
function a(){}
// 先定義函式再定義變數的時候
console.log(typeof b); // function
function b(){}
var b = 2;
不好意思,function有主角光環,不管你變數怎麼調整出場順序,最後的贏家都是function
。
3.let 和 const不會有變數提升這種現象
console. log(a); // Uncaught ReferenceError: a is not defined
console.log(b);
let a = 1;
const b = 2;
按照一般的邏輯,變數應該在宣告語句之後才可以使用,為了糾正變數提升這種現象,let和const改變了語法行為
,它所宣告的變數一定要在聲明後使用
,否則會報錯。