JavaScript 语言的特别之处就在于:函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。
所谓闭包就是说,一个函数能够访问其函数外部作用域中的变量,即指有权访问另一个函数作用域中的变量的函数。而创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。
闭包的作用在于,可以通过闭包,设计私有变量及方法。
闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
案例一:
function outer(a){ var x = 1; function inner(y) { console.log(x+y); } return inner; } var i= outer(3); //其实i内部储存的是inner函数的地址。因为outer() 返回了inner,所以其实i=inner(); i(5); //result: 6 这里就会使用局部变量,打印出a;本层虽没有a的定义,但是在innner的作用域链存在,所以输出1 outer(3)(5); //result: 6 这里是把上面两步合并了一下输出。 inner(); //但是这样调用,是不能成功的,会报错。
案例二:
function outer(){ var x = 1; function inner() { return x++; } return inner; } var x= outer(); console.log(x()); //result: 1 console.log(x()); //result: 2 console.log(x()); //result: 3
为什么是1,2,3呢?因为函数的闭包,记住了定义时所在的作用域,这个作用域中的变量不是一成不变的。
案例三:
function outer(){ var x = 1; function inner() { return x++; } return inner; } var x= outer(); var y = outer(); console.log(x()); //result: 1 console.log(y()); //result: 1 console.log(x()); //result: 2 console.log(y()); //result: 2
这里又为什么结果是这样呢?因为 x和y其实是两个不同的对象,相互之间不影响。 每次调用一个函数,都会产生新的闭包。新的闭包,语句全新,所处环境也是全新的。