學習總結 javascript 閉包

來源:互聯網
上載者:User

標籤:

學習地址 :http://stackoverflow.com/questions/111102/how-do-javascript-closures-work 

1,關於閉包的簡單實現
//example 1
function sayHello(name) {
var words = "hello," + name;


var sayForAlert = function () {
alert(words);
}


sayForAlert();
}
//sayHello("jack");
/*


An Example of a Closure


Two one sentence summaries:


a closure is the local variables for a function — kept alive after the function has returned, or
a closure is a stack-frame which is not deallocated when the function returns (as if a ‘stack-frame‘ were malloc‘ed instead of being on the stack!).
*/




function sayHello2(name){
  var words = "hello, "+name; //local variables;
  var sayForAlert =  function (){
alert(words);
  }
  
  return sayForAlert;
}


var say2 = sayHello2("lucy");
say2();


/*
一個函數的引用,作為一個參數返回回來。在這裡相當於返回一個函數的
指標。sayForAlert 和 say2指向的是同一函數。
javascrip與c的一個重要區別在於c指標指向一個函數,而javascript是一個引用指向一個函數。(相當於是隱藏性指標)。
在許多的語言中和c一樣,當函數執行完成後,本地的變數就不能再訪問。
因為其函數的堆棧被銷毀。
在javascript中函數的裡面可以在聲明函數。並且本地的變數可以訪問,並
可心在聲明的函數中返回。
*/
 


function saynumadd(){
 var num = 666;
 
 var showAlert = function(){
alert(num);
//num++;//place 2;
 }
 num++;//place 1;
 return showAlert;
}


var sayNumber = saynumadd();
sayNumber();//alert 667;
/*
note: 根據上面的執行結果來看num做為一個變數被儲存起來在後面
函數的調用可以再擷取到。 如果我們把num++;放到place2的位置
看到的結果就是666.說明函數的執行順序執行 saynumadd() 執行過程
中 1,聲明變數num,2,聲明函數 showAlert,3,把變數num自增加1;
當我們執行 sayNumber()的時候看到的就是667 增加後被儲存的結果。
*/
function setupSomeGlobals(){
var num = 666;

//store some references to function as global variables
getAlertNumber = function (){
alert(num);
}

getIncreaseNumber = function(){
num ++;
}
getSetNumber = function(x){
num = x;
}
}


setupSomeGlobals();
getIncreaseNumber();
getAlertNumber();
getSetNumber(10);
getAlertNumber();//10


setupSomeGlobals();
getAlertNumber();//666
/*
onte:
從上面的例子可以看出,
setupSomeGlobals 裡面的三個函數被聲明都有許可權去訪問裡面的變數。 


如果我們重新調用 setupSomeGlobals() 新的函數堆棧會被建立. 之前建立的getAlertNumber, getIncreaseNumber, getSetNumber 會被重寫並有一個新的閉包. (在 JavaScript中, 無論任何候都可以在function的內部聲明另外一個function,外面的function被調用的時候,裡面的function都會被重新建立.)
*/


function buildList( list ){
var result = [];
for (var i = 0 ; i<list.length; i ++){
var item = ‘item‘ + list[i];
result.push(function(){alert(item +‘    ‘+list[i])});
}

return result;
}


function testList(){
var fnList = buildList([1,2,3,4]);
for(var j=0; j < fnList.length; j ++){
fnList[j]();
}
}


testList();//alert item1  undefined;
/*
運行結果,可以說明function裡面的function只可以儲存本地變數,不能儲存參數變數。所以我們在使用封包函數要注意其中變數的範圍。
*/


function callLocalVar(){
var sayAlertName = function(){alert(name)}; 
var name = "jacy";

return sayAlertName;
}
callLocalVar()();//這種寫首先會執行callLocalVar再執行返回的sayAlertName;


/*
note:
總結閉包函數可以訪問到同一個域時定義的變數,無論是在這個閉包函數的前面還是後面。 只要是同一個域就可以被訪問到。
*/


function checkClosure(someNum, someRef){

var num = someNum;
var arr = [1,2,3];
var ref = someRef;

return function(x){
num += x;
arr.push(num);
alert(‘num :‘+num + ‘ \n arr :‘+arr.toString()
+‘\n ref.someVar‘+ref.someVar);
}
}


var obj = {someVar:4};
var fn1 = checkClosure(4,obj);
var fn2 = checkClosure(5,obj);


fn1(1);// num: 5; arr: 1,2,3,5; ref.someVar: 4;
fn2(1);// num: 6; arr: 1,2,3,6; ref.someVar: 4;


obj.someVar ++;


fn1(2);// num: 7; arr: 1,2,3,5,7; ref.someVar: 5;
fn2(2);//num: 8; arr: 1,2,3,6,8; ref.someVar: 5;


/*
note:
這裡的寫法解決了參數變數不能被儲存的問題,只要建立一個本地範圍一個變數來接收這個參數變數的值就可以了。
可以說明不同的範圍,互相不影響。
*/

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

學習總結 javascript 閉包

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.