JS閉包

JS作用域

JS的作用域可以分爲全局作用域和局部作用域,全局變量可以在所有的腳本和函數中使用,而如果變量在函數中聲明的,則稱爲局部作用域,局部作用域只能在函數內部訪問


1: 全局變量

<script>

var carName = " Volvo"; 

// 此處可調用 carName 變量 

function myFunction() { 

    // 函數內可調用 carName 變量 

}
</script>

2:局部變量:

        <script>
     // 此處不能調用 carName 變量 
     function myFunction() { 
     var carName = "Volvo"; 
     // 函數內可調用 carName 變量 
     }
    </script>

JS閉包
我們說函數中定義的局部變量只能在函數中起作用,但是通過閉包可以將使函數使用別的函數中的局部變量,但是閉包會大量佔用內存 會導致網頁內存泄露 ---所以一般儘量避免使用閉包
實例:

function f1(){
        var a=10;
        return a;
    }
    function f2(){
        console.log(f1());
    }
    f2();

上面實例中函數2中可以調用函數1中的變量a,輸出結果爲10.
接下來舉一些函數方面的實例,方便更好的理解
1:

     <script>
     function f1(){
         var  a=1;
             var t=function(){
             a++;
             }
             return function(){
              console.log(a);
             }
             }
             var b=f1()
             b();//a=1
             t();
             b();//a=2
             t();
             b();//a=3
     </script>

因爲t()函數是匿名函數,沒有調用不會自己執行,所以當第一次調用f1()函數時,t()函數不執行,當t()執行後,a自加1,返回a等於2,於是第二次調用的時候就會得到a=2的結果,之後同理;而如果把調用函數改爲

 var a1=f1();
a1();//1
t();
var a2=f1();  //重新執行一遍
a2()//1

剛開始做這道題的時候,以爲a2()中得到的結果是a=2,但是當重新定義var a2=f1()時,函數也會重新初始化,所以就算之前執行過一次t()函數,在重新初始化後與a2無關。
2:

    var temp = "object";
(function () {
    console.log(temp);//undefined    //提前聲明
    var temp = "student";
    console.log(temp);//student
})();

這道題在我開始做的時候很難理解,第一個temp爲什麼會是undefinde一直糾結了很久,object是一個全局變量,而student則是函數中的一個局部變量,當在函數中調用student的時候會覆蓋object,又因爲函數中的變量可以被提前聲明,本題就相當於

var temp = "object";
   (function () {
         var  temp;
       console.log(temp);//undefined    //提前聲明
    var temp = "student";
    console.log(temp);//student
})();

所以第一個console.log(temp )的結果就爲undefined,第二個的結果就爲student

3:

 function f1() {
    var n = 999;
    return function f2() {
        return n;
    }
    }
   console.log(f1()());//999
  console.log(f1());//返回return後面的一堆

4:

(1)  var name="global";
              function foo(){
              console.log(name);
               }
              function fooOuter1(){
               var name="local";
               foo();
                 }
              fooOuter1();//global 

     (2)var name="global";
              function fooOuter2(){
                            console.log(name);//undefined
               var name="local";
                function foo(){
                    console.log(name);//local    局部函數取就近
                 }
                foo();
              }
              fooOuter2();//local

這兩個題很相近,但因爲作用域的不同結果截然相反,第一個題中因爲函數中的變量作用域只能作用在本函數中,而不能作用到其他函數中 ,所以在fooOuter1中調用foo函數,foo無法調用fooOuter1中的變量,只能調用全局變量。而如果把題1換一個形式,用閉包,則得到結果爲local

      var name="global";
                function foo(){
                var name="local";
                console.log(name);
                }
                function fooOuter(){
                foo();
                }
                fooOuter()//返回結果爲local

而在題二中,因爲是在函數體中調用,函數體中的local會覆蓋global,所以會先調用local

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章