淺談JavaScript變量聲明提高

前段時間阿里實習生內推,一面就被刷了,也是鬱悶。今天系統給發通知,大體意思就是內推環節不足以瞭解彼此,還能夠參加筆試,因而趕忙再投一次。官網流程顯示筆試時間3月31日,時間快到了,開始刷題。網上搜了一下去年題目,我擦,第一題就不會(傷心中...),繼續往下看,第四題也不會。。。好嘛,搜答案吧。搜了一個多小時的博客,結合本身的理解,寫下了這篇博文。。。javascript

2014年阿里巴巴前端工程師筆試題目1:html

var v = "Hello world";
	(function() {
		console.log(v);
		var v = "I love you";
		bar();
		foo();
		 function bar(){
		 	console.log("this is bar!");
		 }
		 
		 var foo = function() {
		 	console.log("this is foo!");
		 };
		 
	})();
請寫出上面的運行結果並說出背後的理由。
題目4:指出一下代碼的運行結果,並解釋爲何。
function bar() {
	return foo;
	foo = 10;
	function foo() {}
	var foo = 11;
}

alert(typeof bar());

其實上面兩道題考察的核心是同樣的,即JavaScript變量聲明的相關概念,以前瞭解過一點,但瞭解的不是太深。前端

要談JavaScript變量聲明,就離開不了做用域的問題。而JavaScript中沒有相似C,JAVA等語言中的塊級做用域。如:java

#include <studio.h>
int main() {
	int i = 1;
	printf("d%",i); //1
	if(1){
		int i = 2;
		printf("d%",i); //2
	}
	printf("d%",i); //1
	return 0;
}
而JavaScript中相應的輸出結果就變成了1,2,2。緣由就是JavaScript中只有函數做用域,這也是致使JavaScript中一個經典問題的緣由,即循環遍歷DOM節點綁定事件後觸發問題。如:

window.onload = function() {
	var oLi = document.getElementsByTagName("li");
	for(var i=0,len=oLi.length;i<len;i++){
		oLi[i].onclick = function() {
			alert(i);
		};
	}
};
扯得有點遠,下面仍是說一下JavaScript語言中的變量聲明提高的問題吧。

一、當訪問函數內的變量時,JavaScript會按照下面順序查找:瀏覽器

(1)語言級別:默認在所用做用域下的this,arguments前端工程師

(2)傳入參數:函數命名的參數,做用域是當前函數體。函數

(3)函數聲明:如題1中的function bar() {} 與 題4中的function foo() {}this

(4)變量聲明:如var v  與 var foo
二、變量聲明與函數聲明常常被JavaScript引擎隱式的提高到當前做用域的頂部。spa

2.一、變量聲明:.net

局部做用域內聲明變量須要加關鍵詞var,即

function a(){
	console.log(typeof b);
	var b = 3;
}
實際上被解釋成

function a(){
	var b;
	console.log(typeof b);
	b = 3;
}

而若是不加關鍵詞var,則默認引用全局做用域內的相關變量,瀏覽器中即window做用域。如圖:


因此若是你能理解下面代碼的運行結果是a=10,則說明對變量聲明部分已經足夠了解。

<span style="white-space:pre">	</span>var a = 1;
	function b() {
		if(!a) {
			var a = 10;
		}
		alert(a);
	}
	b();
2.二、函數聲明:咱們都知道函數命名有兩種方式,一種是函數聲明方式function bar() {} 另一種就是經過賦值語句的方式,即函數聲明表達式var foo = function() {};

而這兩種函數命名方式雖然都會出現變量聲明提高的現象,但第一種提高現象會包含函數體部分一塊兒被提高,即整個函數bar被提高。而第二種則只是簡單的變量提高(想象一下將賦值語句後面的函數代碼改成基本變量,如數字5,則和上一步所說的變量聲明部分徹底吻合)。

所以得出以下結論:

(1)JavaScript中聲明語句會被提高,而賦值語句不會被提高。

(2)函數聲明提高優先於變量聲明提高。
如今你應該能明白阿里筆試題1中輸出結果是undefined this is bar! error:undefined is not a function. 題4中的結果是function.

特此感謝如下博主的精彩博文:

harmony的專欄《2014年阿里巴巴前端工程師筆試題》

浪跡天涯《JavaScript中變量提高------Hoisting》

Nomospace《翻譯——JavaScript中的變量做用域與變量聲明提高》

相關文章
相關標籤/搜索