我一般都是说,创建一个动态存储空间,突破作用域的限制。让外部可以访问内部的变量,感觉自己答得没什么问题啊,为什么面试完没通知?
ringa_lee
函數內部變數常駐記憶體
函數背著自己的運作環境,像是一隻蝸牛
先給一個理解:閉包是一個函數,保存了自己創建時的環境(一般指父函數中的變數。)程式碼範例:
function foo(){ var a = 1; return fn(){ alert(a); } }
這裡fn就是閉包。 理解前半句後,來看後半句如何理解。
function foo(){ var date = new Date(); //获取当前系统时间的秒数 var a = date.getSeconds(); return function fn(){ console.log(a); } } var f = foo(); f();
在瀏覽器中執行後,開啟控制台;控制台中的數就是目前系統時間的秒數。 (刷新就會變)
這裡的將閉包fn賦給了f,當f執行的時候;fn函數就會被創建,fn函數保存了此時的父環境(即a變數的值)。當再次刷新,fn函數所建立的時間變了;a的值也就變了。
看到這裡應該就知道什麼是閉包了,以下是一個閉包的應用;沒興趣的可不看
<p> <ol id="clotest" start = "0"> <li class="item"></li> <li class="item"></li> <li class="item"></li> <li class="item"></li> </ol> </p> <script type="text/javascript"> var clotest = document.getElementById('clotest'); var nodes = clotest.getElementsByTagName('li'); for(var i = 0; i < nodes.length; i++){ nodes[i].onclick = function(){ alert(i); } } </script>
這裡的需求是點選到哪個清單項目;就會出現哪個值。如點選0號列表,就會跳出0。
但是當你實際點擊的時候,發現彈出的值一直是4。為什麼會出現這種結果呢? 這裡定義一組有序列表;點選到哪個列表項目;就會出現哪個值。如點選0號列表,就會跳出0。 但是當你實際點擊的時候,發現彈出的值一直是4。為什麼會出現這種結果呢?
因為閉包保存的是它被創建時父函數中的變數啊!
電腦讀取程式碼的時候,首先for循環;會給nodes[0]、nodes[1]等四個節點的onclick屬性賦一個匿名函數。 當你點擊某個列表項目的時候,匿名函數正式誕生;此時匿名函數的父函數i的值是4,所以當你點擊任何一個列表項的時候;彈出的都是4。 那怎麼來解決這個問題?
我們需要在每一個node節點綁定的時候,保存下當前i的值。故我們可以定義一個handler的函數,將i當作參數傳給handler函數。
var clotest = document.getElementById('clotest'); var nodes = clotest.getElementsByTagName('li'); for(var i = 0; i < nodes.length; i++){ nodes[i].onclick = handler(i); } function handler(i){ return function(){ alert(i); } }
這就是閉包的第一個作用,保存現場。
函數內部變數常駐記憶體
函數背著自己的運作環境,像是一隻蝸牛
先給一個理解:閉包是一個函數,保存了自己創建時的環境(一般指父函數中的變數。)
程式碼範例:
這裡fn就是閉包。
理解前半句後,來看後半句如何理解。
在瀏覽器中執行後,開啟控制台;控制台中的數就是目前系統時間的秒數。 (刷新就會變)
這裡的將閉包fn賦給了f,當f執行的時候;fn函數就會被創建,fn函數保存了此時的父環境(即a變數的值)。當再次刷新,fn函數所建立的時間變了;a的值也就變了。
看到這裡應該就知道什麼是閉包了,以下是一個閉包的應用;沒興趣的可不看
這裡的需求是點選到哪個清單項目;就會出現哪個值。如點選0號列表,就會跳出0。
但是當你實際點擊的時候,發現彈出的值一直是4。為什麼會出現這種結果呢?
這裡定義一組有序列表;點選到哪個列表項目;就會出現哪個值。如點選0號列表,就會跳出0。
但是當你實際點擊的時候,發現彈出的值一直是4。為什麼會出現這種結果呢?
因為閉包保存的是它被創建時父函數中的變數啊!
電腦讀取程式碼的時候,首先for循環;會給nodes[0]、nodes[1]等四個節點的onclick屬性賦一個匿名函數。
當你點擊某個列表項目的時候,匿名函數正式誕生;此時匿名函數的父函數i的值是4,所以當你點擊任何一個列表項的時候;彈出的都是4。
那怎麼來解決這個問題?
我們需要在每一個node節點綁定的時候,保存下當前i的值。故我們可以定義一個handler的函數,將i當作參數傳給handler函數。
這就是閉包的第一個作用,保存現場。