以下你将了解到:
1、什么是闭包
2、为什么用闭包
3、闭包的使用场景以及注意事项
一、介绍闭包之前,我们先了解下--变量和作用域
1、在 JavaScript 中, 对象和函数同样也是变量
2、作用域:可访问变量的集合
- 局部作用域:变量在函数内部定义【局部变量】,只能在函数内部访问
function initData(){
var name = 'zjl';
console.log('name==>'+name);//name==> zjl
}
console.log('out name==>'+name);//out name==> null
initData();
注:局部变量,在函数执行时被创建,执行结束自动销毁
- 全局作用域:变量在函数外定义【全局变量】
var name = 'zjl';
function initData(){
console.log('name==>'+name);//name==> zjl
}
console.log('out name==>'+name);//out name==> zjl
initData();
注:全局变量在页面关闭后销毁
function initData(){
name = 'zjl';
console.log('name==>'+name);//name==> zjl
}
var name='lisi';
console.log('out name==>'+name);//out name==> lisi
initData();
注1:上面代码,如果在函数initData内部定义变量,不加关键字var即为全局变量 当我们想通过函数外部访问函数内部局部变量,或一个函数访问另一个函数的内部局部变量时,该怎么做呢?这就需要想个办法间接的访问局部变量。闭包就派上了用场,现在我们通过一个例子看看,怎么实现一个闭包:
注2:作用域链是描述一种路径的术语,沿着该路径可以确定变量的值 .当执行name = 'zjl'时,因为没有使用var关键字,因此赋值操作会沿着作用域链到var ='lisi'; 并改变其值.
不用闭包时:out name==> null
function initData(){
var name = 'zjl';
console.log('name==>'+name);//name==> zjl
}
console.log('out name==>'+name);//out name==> null
initData();
用闭包:
var getName = (function initData(){
var name = 'zjl';
function getName(){ return name}
return getName;
})()
console.log('out name==>'+getName());//out name==> zjl
上面的代码,就是一个典型的闭包实现,闭包可以理解为函数内部的函数,这个内部函数可以访问上级作用域变量. 闭包【内部函数】作为,外部函数访问内部变量的桥梁

var getName = (function initData(){
var name = 'zjl';
function getName(){ return name}
return getName;
})()
console.log('out name==>'+getName());//out name==> zjl
由于外函数,被赋值到一个全局的变量getName.由于全局变量常驻内存的,界面不关闭内存得不到释放,局部变量也不会被释放.如果内函数【闭包】循环调用很容易造成内存泄漏.这种情况,在全部函数调用完之后,把不需要的局部变量释放掉.
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function() {
return function() {
return this.name;
};
}
};
alert(object.getNameFunc()()); //The Window
function outerFun() {
var a = 0;
innerFun:function () {
return function(){ a++;}
},
clear:function(){
a=null;
}
}
var obj = outerFun();
obj.innerFun(); //结果为1
obj.innerFun(); //结果为2
var obj2 = outerFun();
obj2.innerFun(); //结果为1
obj2.innerFun(); //结果为2
obj.clear();
obj2.clear();
