js閉包的研究

 

在看書遇到了講解js閉包的地方,講的太學術了 根本不明白 最近在網上搜集了些資料 發現了一些通俗易懂的講解 終於弄明白了閉包

要理解閉包,首先必須理解Javascript特殊的變量做用域。ide

變量的做用域無非就是兩種:全局變量和局部變量。函數

Javascript語言的特殊之處,就在於函數內部能夠直接讀取全局變量。this


Js代碼spa

  var n=10;對象

  function f1(){
alert(n);
}ip

  f1(); //10內存

另外一方面,在函數外部天然沒法讀取函數內的局部變量(而經過閉包的形式就能夠實現)。作用域

Js代碼get

  function f1(){
var n=999;
}

  alert(n); // error

這裏有一個地方須要注意,函數內部聲明變量的時候,必定要使用var命令。若是不用的話,其實是聲明瞭一個全局變量!

Js代碼

function f1(){
n=10;
}

  f1();

  alert(n); // 10

 

 但咱們有時候須要獲得函數內的局部變量,咱們怎麼得到呢?其實經過閉包的形式就能夠實現了。

在Javascript語言中,只有函數內部的子函數才能讀取局部變量,所以能夠把閉包簡單理解成「定義在一個函數內部的函數」。
 因此,在本質上,閉包就是將函數內部和函數外部鏈接起來的一座橋樑

 閉包能夠用在許多地方。它的最大用處有兩個,一個是前面提到的能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中
 如下是個js閉包的使用  其中內部函數getNum()就是個閉包函數, nAdd是個全局的匿名閉包函數

function getcounts(){
   var n = 10;
  
   nAdd = function(count){
       n += count;
   }
  
   function getNum(){
       alert(n);
   }

   return getNum;
}

var one = getcounts();

function gotoPage(){
    one();
 nAdd(2);
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

問題:有關js做用域鏈的問題

var name = "The Window";  
var object = {  
name : "My Object",  
getNameFunc : function(){  
return function(){  
return this.name;  
};  
}  
};  
alert(object.getNameFunc()()); //The Window

最近剛剛研究js閉包 小弟不明白爲何結果是The Window 而不是My Object
name不是全局變量麼? 外層的name不該該被object中的覆蓋麼?

答:

當在函數中訪問一個變量的時候,搜索順序是先搜索自身的活動對象(即return的function),若是存在則返回,若是不存在將繼續做用域鏈 上一個函數(即getNameFunc), 在return 的function做用域中是存在this.name的,即window.name,因此沒有必要再向上一個做用域去找。

function纔是做用域, object={}不是做用域。第一個做用域this就是有的啊,就是window對象,因此不用在找了。

this去掉以後在return function的做用域和getNameFunc的做用域中都找不到name了,只能到全局做用域中找到name = The Window。

var name = "The Window";
var object = {  
name : "My Object",  
getNameFunc : function(){  
return function(){  
return name;  
};  
}  
};  
alert(object.getNameFunc()()); //The Window

 

當你你試着寫成這樣時,由於如今return function的做用域,找不到再到和getNameFunc的做用域中找就找到了name=test var name = "The Window";   var object = {   name: "My Object",   getNameFunc: function () {   var name = "test";   return function () {   return name;   };   }   };   alert(object.getNameFunc()()); //test

相關文章
相關標籤/搜索