本文將從如下幾個點來展開:git
什麼是閉包?怎麼建立閉包?github
閉包的應用閉包
函數執行完,其內部函數還保持着對它的做用域的引用,這個引用就是閉包。ide
內部函數對包含它的函數做用域保持着引用意味着什麼?函數
也就是函數執行完,內存被釋放,可是其做用域還存在內部函數的執行上下文中,還能在內部函數中訪問到函數做用域中的變量。ui
也就是如何讓內部函數對包含它的函數的做用域始終保持引用呢?code
沒有建立閉包的例子:對象
function addValue() { var value = 1 return function add () { return value++ } } console.log( addValue()() ) //1 console.log( addValue()() ) //1
example1的栗子不能算閉包,由於內部函數並無對包含它的函數做用域保持引用。每次調用addValue方法,value都是1。若是像example2同樣將addValue返回的函數賦值給一個全局變量,那麼在程序卸載以前,內部函數一直被全局變量引用着,因此addValue內存始終不會被釋放。以下:ip
建立了閉包的例子:內存
function addValue() { var value = 1 return function add () { return value++ } } var b = addValue() console.log( b() ) //1 console.log( b() ) //2
函數做用域是在執行時建立的,當函數執行完,內存就會被釋放,函數內部變量不能在函數外部被訪問。可是若是函數一直被引用着,那麼函數內存就不會被釋放,函數中的變量就不會被銷燬,包含該函數做用域的函數就能訪問到該函數中的變量。
對於一個函數而言,函數中的變量只能在被激活的時候才能訪問到,也就是在函數內部才能訪問到,當函數執行完內存就會被釋放,也就是函數執行上下文就會被銷燬,對應的執行上下文中的活動對象保存的變量也會被銷燬。
基於js的垃圾(內存)回收機制,若是函數一直被引用着函數一直處於激活(被使用的)狀態,其內存就一直不會被回收,其執行上下文一直存在,保存的變量對象也一直存在。
一、建立私有模塊
var module = (function() { var person = { name: "phillip", age: 29, location: "Utah" }; function privateMethod(){ return "Hi, I'm " + person.name + ", age " + person.age + " from " + person.location; } // Anything that is being returned is made public and can be invoked from // outside our lexical scope return { // Code here. privateMethod: privateMethod }; })(); module.privateMethod()
二、保留記錄
var friends = ["Tom", "Dick", "Harry"]; var secondLevelFriends = ["Anne", "Harry", "Quinton"]; var allUsers = ["Tom", "Dick", "Harry", "Anne", "Quinton", "Katie", "Mary"]; function findPotentialFriends(existingFriends) { return function (friend) { return existingFriends.indexOf(friend) > -1 ? false : true } } var isNotAFriend = findPotentialFriends( friends ); // isNotAFriend(allUsers[0]); // false // isNotAFriend(secondLevelFriends[2]); // true
檢驗閉包掌握狀況:
function fo() { var i = 0; return function (n) { return n+i++ //++ 先賦值再+1 } } var f = fo() console.log(f(15)) //15 console.log(fo()(15)) //15 console.log(fo()(20)) //20 console.log(f(20)) //21
要了解閉包保存函數內部變量的原理,必須瞭解了函數執行上下文、變量對象、做用域鏈、函數做用域、垃圾回收內存釋放的知識,能夠參考下面的文章:
那麼Js中究竟是如何管理變量(何時會被回收內存)的呢?
http://note.youdao.com/notesh...
函數做用域(函數中如何訪問變量呢)是怎麼一回事呢?
http://note.youdao.com/notesh...