JavaScript重要概念之闭包

119 阅读2分钟

概念

闭包是一种特殊的对象。
由两部分组成。

  • 一个执行上下文A 以及在该执行上下文创建的函数B
  • 当函数B执行时,访问到了A中变量对象的值,那么闭包就会产生。
var fn = null
function foo(){
	var a = 2;
  function innerFoo(){
  	console.log(a)
  }
  fn = innerFoo
}
fn() // fn = function(){ console.log(a) }
// 一个执行上下文A  这里是函数foo的执行上下文  
// 在执行上下文A定义的函数B 这里指 innerFoo
// 当函数B执行时访问了A中的变量 这里指 fn()  console.log(a) 访问了变量a

代称

在大所数理解都把函数B 代称为这里生成的闭包(函数B)
在chrome中,则以执行上下文A的函数名来代指闭包(执行上下文A)

用处

  1. 通过闭包,可以在其他的执行上下文中,访问到函数的内部变量

上面例子中,fn就访问到变量 a

  1. 模块化: 使用函数自执行的方式,创建一个模块,可以将方法利用闭包向外暴露出去,作为模块的公有方法。
  2. 柯里化

注意

function count(){
	var arr = []
  for(var i = 0;i<=3;i++){
  	arr.push(function(){ return i*i} )
  }
  return arr
}
// 函数做了什么
// 循环i 每循环一次 向arr中添加一个函数作为元素。
var result = count()
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
// 这里闭包指的是哪一个?
// count
f1()//16
f2()//16
f3()//16
// 预期结果 是 1 4 9
// 要达到预期结果需要怎么修改
//...
 for (var i=1; i<=3; i++) {
        arr.push((function (n) {
            return function () {
                return n * n;
            }
        })(i));
    }
//...
// 在外面再包裹一个函数,将循环变量作为参数传递进去,
//无论该循环变量后续如何更改,已绑定到函数的参数的值不变
// 这里使用了“ 创建一个匿名函数并立即执行”的语法
  1. 返回闭包时,返回函数不要引用任何循环变量,或者后续会发生变化的变量。