JavaScript必須要掌握的知識-作用域編寫提升

智雲程式設計發表於2019-07-10

提升什麼?

把變數與函式的宣告移到編寫所處作用域的最上面,叫作 提升

如下程式碼:

console.log(name); // undefined
var name = 'Rewa Fang';
console.log(name); // Rewa Fang

第一次列印 name 時,輸出 undefined 而不是丟擲異常 ReferenceError 。 正是因為變數 name 宣告被提升了。 但只提升宣告,賦值不會提升;所以輸出 undefined 。 第二次列印時, name 已經被賦值為 Rewa Fang

提升後的程式碼:

var name;
console.log(name); // undefined
name = 'Rewa Fang';
console.log(name); // Rewa Fang

程式碼改成下面這種寫法也是可正常執行的:

name = 'Rewa Fang';
console.log(name); // Rewa Fang 
var name;

var name;  會被提升到最上面。

這是因為編譯器在編譯階段會找到程式碼中所有的 宣告 ,並繫結在對應的作用域中。而賦值和其它邏輯程式碼會留在原地;等待執行。 比如:  var a = 1;  會被編譯器看作兩個部分宣告 var a; 和賦值 a = 1;  ,那麼宣告會提升到作用域最上面,賦值則在原地等執行。

包含函式宣告也會提升。

函式宣告提升

sayHi(); // Hello!
function sayHi(){
    console.log('Hello!');
}

函式sayHi()可以正常執行;因為函式宣告的部分被提升了。提升為:

function sayHi(){
    console.log('Hello!');
}
sayHi(); // Hello!

函式內部的變數和函式也會提升至函式最上面:

var name = 'Lebron James';
sayHi(); // Hello! Rewa Fang
function sayHi(){
    name = 'Rewa Fang';
    console.log('Hello! '+name);
    var name;
}

函式內的name會提升至函式建立的作用域最上面,所以函式內部不會引用到外部name。 內部的name遮蔽了外部變數name。

提升後:

function sayHi(){
    var name;
    name = 'Rewa Fang';
    console.log('Hello! '+name);
}
var name;
name = 'Lebron James';
sayHi(); // Hello! Rewa Fang

提升後有一個變化,就是 函式宣告會優先於變數提升

比如:

console.log(sayHi);
var sayHi = 'Lebron James';
function sayHi(){
    console.log('Hello! ');
}

結果會輸出: ƒ sayHi(){console.log('Hello! ');}  node環境下輸出: [Function: sayHi]

why ?

為什麼需要提升?

有以下原因:

  • 最佳化效能; 編譯器在程式碼執行前進行編譯會預先處理變數和函式的宣告,統一管理作用域。保持程式碼由上而下的順序變數在引用之前宣告。 不過程式碼的順序是可以人為控制的,像Java不需要提升開發者可以有效地管理好變數的宣告。 所以這可能並不是最重要的提升原因,也可能是個歷史遺留問題。

  • 函式間的相互呼叫; 如下程式碼,如果函式b沒有提升; 函式a中呼叫就會丟擲異常;提升就可以讓函數語言程式設計變得更靈活。

     function a (){
        var a = 1;
         return b(a);
     }
     function b(num){
        return num * 2;
     }
    

PS: ES6中 let const 不會被提升

多年程式設計經驗,月初整理了一批2019年最新WEB前端教學影片,不論是零基礎想要學習前端還是學完在工作想要提升自己,這些資料都會給你帶來幫助,從最基礎的HTML+CSS+JS【炫酷特效,遊戲,外掛封裝,設計模式】資料都有整理,幫助所有想要學好前端的同學,學習規劃、學習路線、學習資料、問題解答。只要加入WEB前端學習交流qun:767,273,102 ,即可免費獲取,學習不怕從零開始,就怕從不開始。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2650118/,如需轉載,請註明出處,否則將追究法律責任。

相關文章