淺談JavaScript 函數作用域當中的“提升”現象


在JavaScript當中,定義變量通過var操作符+變量名。但是不加 var 操作符,直接賦值也是可以的。
例如 : message = "hello JavaScript ! " 即定義了一個全局變量message,並賦值 “Hello JavaScript!”
--《JavaScript高級程序第三版》

如同往日一般,一群人在所謂的技術交流群里面相互斗圖着。突然老王莫名的正經起來,在群里發了一道JavaScript的題目,讓大家猜一猜這道題的答案。

var foo = 1;
	function bar() {
		foo = 10;
		return;
		function foo() {}
	}
	bar();
	console.log(foo);  //求控制台輸出多少?

看到這到題目之后,立刻不加思索回答了“10”。
首先第一步定義一個全局變量 foo = 1,然后函數執行的時候又定義全局變量 foo = 10覆蓋了之前的全局變量,return之后,這個函數就直接結束, function foo {}來不及定義。因此控制台輸出10;
按照在《高三》上面看到知識點推斷,毫無問題,簡直完美呀!

給自己32個贊!
【給自己32個贊!】

但是,在把答案發出去之后。本能就感覺這道題不可能這么簡單,不正經的群突然討論正經的代碼,肯定會有大坑等着人來跳。一種不好感覺涌上心頭,感覺自己又要被打臉了。

趕緊打開編輯器測試一下這段代碼,手哆嗦的按下F12.只見控制台下,一個耀眼的1赫然闖入眼簾。啪啪啪!!這臉又被打的,好疼呀!!

為什么被打臉的總是我!!
【為什么被打臉的總是我!!】

果不其然群里老王馬上的在群里否決我的答案,啪的一下打了這張老臉。
不行!這個臉打了得把場子找回來,這個老王接下來肯定會揭曉答案並公布解題思路。得在他公布之前,講答案和原因給測試出來。

經過簡單的測試之后,發現原來是后面的foo,函數提升到最頂端了。所以后面foo = 10中的foo實際上是一個局部變量了。因此后面console.log(foo)時是拿不到bar函數中的局部變量foo = 10,因此只能拿到全局變量foo = 1;所以控制台輸出1。

上文代碼的另外一種形式:
var foo = 1;
	function bar() {
		function foo(){}
		foo = 10;
		return;
	//	function foo() {}    相當於這行代碼提升到最頂部了
	}
	bar();
	console.log(foo); 

被搶了風頭的老王果斷的不服氣呀!說我瞎猜扯犢子一廂情願的,自己隨意猜想的。
好的,下面就是開始解釋我為什么說函數function foo(){}提升到最頂端。不改動老王的代碼,讓我們只是加兩個console.log測試一下相應的輸出結果。

var foo = 1;
	console.log("全局變量:foo = " + window.foo)
	function bar() {
		console.log("此時bar函數中foo =" + foo)
		foo = 10;
		console.log("bar函數中的變量是" + foo);
		console.log("全局變量foo還是:"+window.foo);
		return;
		function foo() {}
	}
	bar();
	console.log(foo); 
瀏覽器輸出結果

瀏覽器測試結果

通過這里可以證實我的猜想是正確的,function foo(){}直接被提升到bar()函數最頂端,然后后面foo = 10就不是再重新定義全局變量了,這里foo是一個局部變量的角色被定義出現的。因此才沒有將全局變量給覆蓋,而由於函數外面是不能直接拿到bar函數當中的局部變量foo,因此繼續向上尋找到全局變量foo = 1.從而輸出1.

我臉都這么紅了,應該不用打臉了

這里估計聯想能力豐富的小伙伴肯定會舉手說,那么函數有提升的現象。那么變量也是否會有提升現象?不錯!不錯!!這位小伙伴聯想的非常正確,學習就要多學會舉一反三。

獎勵一朵小紅花
【獎勵一朵小紅花】

變量提升
var foo = 1;
	function bar() {
		foo = 10;
		return;
		var foo   //幾乎是相同的代碼,只是把 function foo  變成了   var  foo。變量也是能夠提升了的!
	}
	bar();
	console.log(foo);  //還是輸出1.
思考:

同樣的既然變量能夠提升,函數聲明能夠提升。那么誰升的更高呢?

function test(){
		console.log(dabang);
		function dabang(){};
		var dabang;
	}
	test();
	
function test1(){
		console.log(dabang);
		var dabang;
		function dabang(){};
		
	}
	test1();

控制台輸出結果:

大棒聲明的函數那必須升的高呀!!!
【大棒聲明的函數那必須升的高!!!】

小結:

1、在JavaScript當中,函數作用域當中。變量和聲明函數都能夠提升。
2、同樣提升的情況下,聲明函數提升的更加高!

以上就是鄙人對於JavaScript函數作用域中“提升現象”一點簡單理解,歡迎各位的大佬們指導學習。
ps:打臉也是可以的,畢竟錯了就是錯了。(那是打臉可否輕一點,留着日后再打呀!(~ ̄▽ ̄)~)

吾雖浪跡天涯,卻從未迷失本心!吾雖惡搞不斷,卻不敢胡亂代碼!
【吾雖浪跡天涯,卻從未迷失本心!吾雖惡搞不斷,卻不敢胡亂代碼!】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM