首頁 >web前端 >js教程 >JavaScript中var宣告方式與變數作用域實例詳解

JavaScript中var宣告方式與變數作用域實例詳解

伊谢尔伦
伊谢尔伦原創
2017-07-18 10:06:211511瀏覽

當你在當前上下文內進行這種「隱式」聲明時,JavaScript引擎會先在當前上下文中尋找是否之前有聲明此變量,如果沒有,再到上一級的上下文中去尋找,如果一直找不到,會最後在window上宣告這個變數! 

window. y = "hello"; 
function func(){ 
y = "OH, NO!!!"; 
} 
func(); 
alert(window.y); //#=> display "OH, NO!!!"

當上下文中的任一層有這種「隱式」定義的變數時,那麼該層的該變數會被修改,而不會在window上產生一個新的變數。

var x = "window.x"; 
function a() { 
var x = "a's x"; 
var b = function() { 
var c = function() { 
//no var! 
x = "c's x:"; 
}; 
alert("before c run,the b.x:" + x); 
c(); 
alert("after c run, the b.x:" + x); 
}; 
alert("a.x is:" + x); 
b(); 
alert("after b function runed, the a.x is:" + x); 
}; 
alert("before a run, window.x:" + x); 
a(); 
alert("after a run, window.x:" + x);

由一段問題引發的思考

一、迷思!由一段程式碼引發的疑惑 

for(var i=0;i<3;i++) { 
console.log(j+","+k); 
for(var j=0;j<3;j++) { 
var k = j+1; 
} 
} 
console.log(i);

輸出結果:

undefined,undefined 
3,3 
3,3 
3

如果你是搞c、java等語言的,可能你會不解,為何j、k這種局部變數可以被作用域外的程式碼存取呢?
如果JavaScript中用var宣告的變數可視為局部變量,那麼能存取這個變數的作用域就是這個變數的局部作用域。如上例,在console.log行處,依然有j、k的作用域,而循環外,依然有i的作用域。說到這裡,也許我可以武斷的說,JavaScript沒有真正意義的局部作用域。真的嗎?非也!

二、如何得到真正的局部作用域呢?一個寫法引起了我的注意
大家也許看過JQuery的源碼或者Ext的源碼,也許會對下面的寫法有點熟悉。

var a = 3,b=4; 
var exports = (function() { 
var a = 1,b=2; 
return {a:a,b:b}; 
})(); 
console.log(""+a+","+b); 
console.log(exports.a+","+exports.b);

輸出結果:

3,4 
1,2

很神奇的發現(其實也不神奇,大家都知道啦)函數內部是有獨立作用域的,即函數內部var聲明的變量,僅在函數內部可用。所以各框架各大師都這麼寫,防止自身局部變數與外界變數(外層局部變數與全域變數)衝突。
至此,我收回第一條裡的武斷推斷,修改一下:
JavaScript以函數為界,每個函數內部擁有一個局部作用域;任何其他的區塊(包括普通程式碼區塊,for循環、 if、while等程式碼區塊)不存在局部作用域,使用var宣告的變數可以直接穿過這些程式碼區塊,可以被外部程式碼存取。

三、何時報錯,何時undefined? var的宣告機制
看程式碼: 

console.log(a)
ReferenceError: a is not defined
undefined
var exports = (function() { 
var a = 1,b=2; 
return {a:a,b:b}; 
})(); 
console.log(a);

#輸出結果:

ReferenceError: a is not defined

猜想結論:
每次JavaScript引擎執行程式碼時,會先掃描作用域中的所有程式碼(作用域中的function內部的程式碼不會掃描),並將所有var宣告的變數記錄下來,在程式碼執行到賦值之前,這些變數的值為undefined。此後如果訪問變數時,先訪問局部變量,如果沒有這個局部變量就訪問上一層的局部變量(如為閉包,上一層為閉包創建環境),直到訪問到完全局變量。如果都沒有這個變量,那麼拋出異常。


以上是JavaScript中var宣告方式與變數作用域實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn