javascript的變量範圍

javascript裏的變量範圍一直比較搞腦子,其實弄懂了一點也不復雜javascript

入門知識

在瞭解以前,須要看懂如下2個語句java

var left1="right";
left2="right";

我解釋一下code

  1. 第一句的意思是先聲明一個名字爲left1的變量,聲明完後,再將值「right」賦給這個left1變量
  2. 第二句的意思是,將值「right」賦給名字爲left2的變量,並無「聲明」這個動做,須要注意如下幾點:
  3. 在賦值前,若是並無寫過聲明變量left2的語句(即 「var left2;」),則javascript會隱性的聲明此變量,而後再進行賦值

做用域範圍

在javascript中,一個做用域裏的一個變量是全局的,正由於是全局的,因此該變量在其子做用域裏也爲可見狀態 ###變量是全局的(初版)### 輸出結果是**oneone**ip

<script language="javascript">
    var left="one";//聲明一個變量,自動變成全局變量
    function f() {   //這個f牌方法算是一個子做用域,因爲變量left是全局的,因此在f牌方法下left是能夠看見的,也是起做用的
    	document.write(left); //第一個打印出來的one是因該句的做用打出
    }
    f();//調用f牌方法,打印出第一個one
    document.write(left);//第二個打印出來的one是因該句的做用打出
</script>

沒什麼好說的看註釋吧,但我比較好奇,改一下代碼看看會怎樣,因而有了第二版 ###變量是全局的(第二版)### 輸出結果是**twotwo**作用域

<script language="javascript">
    var left="one";
    function f() {   
            left="two";  //我就加了這一行++++++++++++++++++++++++++
            document.write(left); 
    }
    f();//調用f牌方法
    document.write(left);
</script>

這個也很好理解,在打印前,變量left被從新賦值了,繼續看下一版吧 ###變量是全局的(第三版)### 輸出結果是**twoonetwo**it

<script language="javascript">
    var left="one";
    function f() {   
            var left;  //我又加了這一行++++++++++++++++++++++++++
            left="two";  
            document.write(left); //打印出two
    }
    f();//調用f牌方法
    document.write(left);//打印出one
    f();//調用f牌方法,也加了這一行++++++++++++++++++++++++++
</script>

第三版就比較關鍵了
在子做用域下(就是那個f牌方法體啦)又聲明(注意前面有var的哦)了一個同名的變量left
那麼該變量left,在當前做用域內(也就是f的方法體內)是全局變量,而之前那個記錄爲one的left在當前做用域會消失不見,而在外面(f方法體的外面)是可見的,兩個left變量相互隔離的
這點必須理解,才能繼續 ###喜歡捉迷藏的undefined(初版)### 先從簡單的出發io

第一段不解釋,打印出one
<script language="javascript">
    var left;
    left="one";
    document.write(left);//打印出one
</script>

第二段不解釋,打印出undefined
<script language="javascript">
    var left;
    document.write(left);//打印出undefined
</script>


第三段,打印出undefined,由於打印在先,聲明在後
<script language="javascript">
    document.write(left);//打印出undefined
    var left;
    left="one";
</script>

第四段,left變量在賦值前沒有聲明過,javascript會隱形的幫你自動聲明一下left
致使第二行的聲明語句無效,屬於重複聲明,但也不報錯
<script language="javascript">
    left="one";//兩行顛倒後
    var left;    //這行成爲無效代碼
    document.write(left);//打印出one
</script>

###喜歡捉迷藏的undefined(第二版)### 加入一個子做用域,也就是f方法體入門

第一段,打印出undefined,left爲全局變量,子做用域也屬於全局的範圍以內
<script language="javascript">
    var left;
    function f() {   
            document.write(left); //打印出undefined
    }
    f();
</script>

第二段,打印出one,理由同上
<script language="javascript">
    var left;
    left="one";
    function f() {   
            document.write(left); //打印出one
    }
    f();
</script>

第三段(關鍵),打印出undefined,子做用域有聲明語句,父做用域的left被隱藏
<script language="javascript">
    var left;
    left="one";
    function f() { 
            var left;//聲明一個變量left  
            document.write(left); //打印出undefined
    }
    f();
</script>

第四段,同上,打印出two,子做用域有聲明語句,父做用域的left被隱藏
<script language="javascript">
    var left;
    left="one";
    function f() { 
            var left;//聲明一個變量left  
            left="two";
            document.write(left); //打印出two
    }
    f();
</script>

第五段(關鍵),打印出twoone,f方法執行完後,f方法裏的left變量被銷燬,父做用域的left又回來了
<script language="javascript">
    var left;
    left="one";
    function f() { 
            var left;//聲明一個變量left  
            left="two";
            document.write(left); //打印出two
    }
    f();
    document.write(left); //打印出one
</script>

第六段(關鍵中的關鍵),打印出undefinedone
只要一個做用域裏有var left;語句,不管出如今第一行仍是最後一行,那這個left就是新的子做用域的全局變量
簡單點說就是,當程序執行document.write這個命令前,就已經把當前的做用域的聲明語句(var開頭的語句)先執行了
即使var是寫在write後面,但仍是var先執行
<script language="javascript">
    var left;
    left="one";
    function f() { 
            document.write(left); //打印出undefined
            var left;//聲明一個變量left
    }
    f();
    document.write(left); //打印出one
</script>

###喜歡捉迷藏的undefined(第三版)### 那開始捉迷藏吧function

第一段變量

<script language="javascript">
    var left;
    left="one";
    function f() { 
            left="two";
            document.write(left); 
    }
    f();
    document.write(left); 
</script>

會打印出什麼呢?twotwo

第二段

<script language="javascript">
    var left;
    left="one";
    function f() { 
            left="two";
            document.write(left); 
    }
    document.write(left); 
    f();
</script>

會打印出什麼呢?onetwo

第三段

<script language="javascript">
    var left;
    left="one";
    function f() { 
            left="two";
            document.write(left); 
    }
    document.write(left); 
    f();
    document.write(left); 
</script>

會打印出什麼呢?onetwotwo

第四段

<script language="javascript">
    var left;
    function f() { 
            document.write(left); 
            left="two";
    }
    document.write(left); 
    f();
    document.write(left); 
</script>

會打印出什麼呢?undefinedundefinedtwo

以上四段裏,始終只有一個做用域,不存在兩個left變量互相打架的狀況,應該比較好判斷吧,繼續看下去 下面是兩個做用域了,開始打架了

第五段(請對比第三段)

<script language="javascript">
    var left;
    left="one";
    function f() { 
            var left="two";
            document.write(left); 
    }
    document.write(left); 
    f();
    document.write(left); 
</script>

會打印出什麼呢?onetwoone

第六段(請對比第四段)

<script language="javascript">
    var left;
    left="one";
    function f() { 
            var left;
            document.write(left); 
            left="two";
    }
    document.write(left); 
    f();
    document.write(left); 
</script>

會打印出什麼呢?oneundefinedone

第六段

<script language="javascript">
    var left;
    left="one";
    function f() { 
            document.write(left); 
            var left="two";
    }
    document.write(left); 
    f();
    document.write(left); 
</script>

會打印出什麼呢?oneundefinedone 這段和第五段類似,var left="two"; 能夠當作var left;+left="two";var left;會浮到最上面優先執行,因此和第五段類似

第七段

<script language="javascript">
    var left;
    left="one";
    function f() { 
            document.write(left); 
            var left="two";
            document.write(left); 
    }
    document.write(left); 
    f();
    document.write(left); 
</script>

會打印出什麼呢?oneundefinedtwoone,不解釋

相關文章
相關標籤/搜索