1
2
3
4
5
6
7
8
9
10
|
<script type=
"text/javascript"
>
var
a = 1;
function
hehe()
{
window.alert(a);
var
a = 2;
window.alert(a);
}
hehe();
</script>
|
執行結果如下所示:
第一個alert:
第二個alert:
這是一個令人詫異的結果,為什么第一個彈出框顯示的是undefined,而不是1呢?
一個頁面里直接定義在script標簽下的變量是全局變量即屬於window對象的變量,按照javascript作用域鏈的原理,當一個變量在當前作用域下找不到該變量的定義,那么javascript引擎就會沿着作用域鏈往上找直到在全局作用域里查找。
首先這段程序涉及到了以下三個概念 執行環境、變量對象、 作用域鏈、 js的執行環境分全局的(瀏覽器的話就是window執行環境)和function執行環境,變量對象是用來保存執行環境下的變量和方法的,而作用域鏈上放着一個一個的變量對象形成一個鏈條。 這段代碼的執行過程應該是這樣的 首先進入全局執行環境 建立該執行環境下的變量對象A(保存有該執行環境下的x和一個匿名方法),再往下執行到匿名方法的執行環境 建立變量對象B(保存有該執行環境下的x),而js的當前執行環境的變量對象永遠放在作用域鏈的最前端,所在執行第一個alert(x), 就會找當前執行環境的變量對象B是否保存有x, 而事實上是有的,但alert(x)之前沒有給x賦值,所出得到的結果就是undefined, 如果變量對象B中不存在x,那么程序就會順着作用域鏈找上一個變量對象A里是否有x.
js的變量有兩種作用域:全局變量和局部變量。沒有使用 var 聲明的變量和在function之外聲明的變量都是全局變量,是window屬性之一;使用 var 聲明的變量屬於所在函數,不管在函數的哪個位置出現,等價於在函數一開始聲明。局部變量比同名全局變量的優先級高,所以局部變量會隱藏同名的全局變量。要想訪問被隱藏的全局變量就加上 window. 前綴。
js沒有塊作用域,在語句塊之后,在函數結束之前,語句塊定義的變量都是可以訪問的。比如:for(var idx =0; idx<2;idx++){} alert(idx); 結果顯示為2。
上段代碼相當於
1
2
3
4
5
6
7
|
var
x=1;
function
(){
var
x;
alert(x);
x=1212;
alert(x);
}
|
正確代碼:第一次要this.x
1
2
3
4
5
6
7
8
9
10
|
<script type=
"text/javascript"
>
var
a = 1;
function
hehe()
{
window.alert(
this
.a);
var
a = 2;
window.alert(a);
}
hehe();
</script>
|