【问】js中的闭包是什么,有什么用?
【答】声明在函数中的函数,形成闭包;主要作用是给外部环境访问函数内部变量提供了桥梁。表现形式上,最常见的是父函数返回了一个子函数,子函数使用到了父函数的变量。被外部不同变量引用的闭包函数,都会形成一个新的执行环境,该执行环境及其状态在引用期间都不会被销毁。闭包有如下特点:1. 局部变量会贮存在内存中,2.可以避免使用全局变量,防止全局变量污染 。
【测试1】
- 示例1
function outerFn(){
var i = 0;
function innerFn(){
i++;
console.log(i);
}
return innerFn;
}
var inner = outerFn(); //被外部引用到的闭包,会保存状态
inner(); //1
inner(); //2
var inner2 = outerFn(); //被外部引用到的闭包,会保存状态
inner2(); //1
inner2(); //2
outerFn()(); //1 //没有 被外部引用到的闭包,状态一直是初始状态
outerFn()(); //1 //没有 被外部引用到的闭包,状态一直是初始状态
- 示例2
function fn(){
var arr = [];
for(var i = 0;i < 5;i ++){
arr[i] = (function(i){
return function (){
return i;
};
})(i);
}
return arr;
}
var list = fn();
for(var i = 0; i < list.length; i ++){
console.log(list[i]());
}
【扩展1】利用闭包实现单例模式
var globalInstance = (function(){
var globalInstanceClass = function (str){
this.msg = str || "哈哈1"
};
var instance = null;
return function (str){
if (!instance){
instance = new globalInstanceClass(str);
}
return instance;
}
})()
var a = new globalInstance();
var b = new globalInstance('bb');
var c = new globalInstance();
//只会创建a一次实例,后面的b和c都不会新创建实例
console.log('a===b', a===b);
console.log('a===c', a===c);
console.log('b===c', b===c);
console.log('a.msg', a.msg);
console.log('b.msg', b.msg);
console.log('c.msg', c.msg);