1.全局变量和局部变量
在学习闭包之前,需要先理解全局变量和局部变量的区别。
举个栗子:
【这个 a 是一个局部变量】
局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。
function myFunction() {
var a = 4;
return a * a;
}
【这个 a 是一个全局变量】
在web页面中全局变量属于 window 对象。全局变量可应用于页面上的所有脚本。
var a = 4;
function myFunction() {
return a * a;
}
全局和局部变量即便名称相同,它们也是两个不同的变量。修改其中一个,不会影响另一个的值。
变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。
2.变量的生命周期
全局变量的作用域是全局性的,即在整个js程序中,全局变量处处都在。
局部变量是在函数内部声明的变量,只在函数内部起作用,作用域是局部性的。
函数的参数也是局部性的,只在函数内部起作用。
3.闭包
闭包函数——声明在一个函数中的函数
闭包:内部函数总是可以访问其所在的内部函数中声明的参数和变量
闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。 直观的说就是形成一个不销毁的栈环境。
function funA(){
var a=10;
return function(){
alert(a);}
}
funA()();//调用函数
闭包会造成内存泄漏:
key=value,键被删除了,但是值还在内存里
4.几个栗子
1.i为全局变量,每次调用函数之后i的值改变会被存储,下次调用函数时i的值是上一次调用改变后的值
var i = 0;
function outerFn(){
function innnerFn(){
i++;
console.log(i);
}
return innnerFn;
}
var inner1 = outerFn();
var inner2 = outerFn();
inner1();//1
inner2();//2
inner1();//3
inner2();//4
2.i定义在outerFn()函数的内部,每次调用时i都会被重新赋值为0,因此第一次调用的inner1和inner2的值都是1,第二次重新调用innerFn()函数,结果会在第一次调用的基础上加1
function outerFn(){
var i = 0;
function innnerFn(){
i++;
console.log(i);
}
return innnerFn;
}
var inner1 = outerFn();
var inner2 = outerFn();
inner1();//1
inner2();//1
inner1();//2
inner2();//2
3.分解一下:
调用add(1)的结果是1
调用add(1)(2)的结果是3
调用add(1)(2)(3)的结果是6
var add = function(x) {
var sum = 1;
var tmp = function(x) {
sum = sum + x;
return tmp;
}
tmp.toString = function() {
return sum;
}
return tmp;
}
alert(add(1)(2)(3)); //6