本文将从如下几个点来展开: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...