1. 程式人生 > 其它 >深入理解js變數提升和函式提升

深入理解js變數提升和函式提升

技術標籤:javascriptjavascript

目錄

提升的定義

變數提升

函式提升

函式優先

函式宣告覆蓋

總結


提升的定義

無論作用域中的宣告出現在什麼地方,都將在程式碼被執行前先進行處理,將所有的宣告移動到各自作用域的頂端,這個過程叫提升。

變數提升

a=2;
var a;
console.log(a);

這段程式碼console會列印什麼呢?也許是undefined,但其實會列印 2 。因為這段程式碼實際會被這樣處理:

var a;
a=2;
console.log(a);

其中:var a;是編譯,後面的兩句才是執行。

再來看一段:

console.log(a);
var a=2;

它會被處理成這個樣子

var a;
console.log(a);
a=2;

同樣的 var a;是編譯,後面兩句是執行,因為a=2賦值是在列印之後,所以這段程式碼會輸出 undefined.。

從上面兩段程式碼就可以知道 以var這樣宣告的變數,放到哪裡都會在編譯階段被移動到當前作用域的最上面。

函式提升

函式的宣告跟變數宣告也是一樣會被提升,下面看函式的例項:

hello();//執行
function hello(){//函式宣告,這裡可以看到宣告在後,執行在前,能正常執行嗎?
	console.log('hello');
}

我們執行這段程式碼,可以看到是正常輸出的,也就是函式宣告被提升了。

那如果我們用var 來宣告函式會怎麼樣呢?

hello();//執行
var hello = function (){
	console.log('hello');
}

執行會報錯:

為什麼呢?因為var hello = function (){
console.log('hello');
} 這樣寫的話var hello是變數宣告,後面的是賦值操作,變數被提升了,賦值操作是沒有被提升的,其實這段等同於這樣:

var hello;
hello();//執行
hello = function(){
	console.log('hello');
}

在執行的時候hello是隻被宣告的,它的值是undefined,所以用()來呼叫會出現TypeError,改成下面這樣才能正常工作,想用這種方式寫,需要將其放到函式執行的前面:

var hello= function(){
	console.log('hello');
}
hello();//執行

函式優先

hello();//執行

var hello;

function hello(){
	console.log('log hello');
}

hello = function(){
	console.log('log hello1');
}

這段程式碼會打印出:log hello

從結果中可以看到函式執行的時候是列印了log hello,函式執行完以後hello變數會被賦值語句替換成列印log hello1的函式,為啥?實際這段程式碼會被處理成這樣

function hello(){
	console.log('log hello');
}

hello();//執行
//var hello這句被忽略了
hello = function(){
	console.log('log hello1');
}

函式優先提升到最上面,此時在用宣告var hello將被忽略,因為此時已經存在hello了,他是一個函式,那接下來執行函式hello當然就打印出之前的結果,然後才被替換。

函式宣告覆蓋

hello();//執行

function hello(){
	console.log('log hello');
}

function hello(){
	console.log('log hello2');
}


function hello(){
	console.log('log hello3');
}

列印的是log hello3,後面的函式宣告把前面的函式宣告都覆蓋了。

總結

函式宣告和變數宣告都會被提升到當前作用域的最上方,並且是函式優先,也就是宣告語句我們在放在什麼位置都可以。

但是為了程式碼好看、好維護、為了避免重複宣告以及避免不必要的風險,還是儘量的把宣告放到最前面。