闭包
闭包就是能够读取其他函数内部变量的函数
通俗讲:内部的函数,被保存到了外部,会生成闭包
function a() {
function b() {
var bbb = 234;
document.write(aaa)
}
var aaa = 123;
return b;
}
var glob = 100;
var demo = a();
demo();
//a()执行,将b()方法返回,b()保存了a()的劳动成果
过程分析图
function a() {
var num = 100;
function b() {
num ++ ;
console.log(num);
}
return b;
}
var demo = a();
demo();// 101
demo();// 102
当内部函数被保存到外部时,将会生成闭包.闭包会导致原有作用域链不释放,造成内存泄露.
闭包的作用
- 实现公有变量
- 函数累加器(不依赖于外部变量)
- 可以做缓存(存储结构)
- 可以实现封装,属性私有化
- 模块化开发,防止污染全局变量
//利用闭包实现累加器
function add() {
var count = 0;
function demo() {
count ++;
console.log(count);
}
return demo;
}
var counter = add();
counter();
counter();
counter();
function test() {
var num = 100;
function a() {
num++;
console.log(num);
}
function b() {
num --;
console.log(num);
}
return [a,b];
}
var myArr = test();
myArr[0]();//101
myArr[1]();//100
// 缓存应用
function eater() {
var food = "";
var obj = {
eat : function () {
if(food != ''){
console.log("i am eating " + food);
food = "";
}else {
console.log("There is nothing!")
}
},
push : function (myFood) {
food = myFood;
}
};
return obj;
}
var eater1 = eater();
eater1.push('banana');
eater1.eat();
// 函数被保存到了外部,当执行的时候,i已经发生了改变
function test() {
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
document.write(i + " ");
}
}
return arr;
}
var myArr = test();
for (var i = 0; i < 10; i++) {
myArr[i]();//全部打印10 原因,arr中的函数都指向的是test中i的变量,i变量在for循环结束后已经变成了10
}
// 上面的函数全部打印10,如果想要打印i的循环过程呢???
// 解决用立即执行函数
function test() {
var arr = [];
for (var i = 0; i < 10; i++) {
(function (j) {
arr[j] = function () {
document.write(j + " ");
}
}(i))
}
return arr;
}
var myArr = test();
for (var i = 0; i < 10; i++) {
myArr[i]();// 打印你想要的结果0,1,2,3...
}
// 属性私有化
function Deng(name, wife) {
var prepareWife = 'xiaozhang';
this.name = name;
this.wife = wife;
this.divorce = function () {
this.wife = prepareWife;
};
this.changePrepareWife = function (target) {
prepareWife = target;
};
this.sayPrepareWife = function () {
console.log(prepareWife);
}
}
var deng = new Deng('deng', 'xiaoliu');
deng.divorce();
// 由于闭包 prepareWife 变成 私有化变量
console.log(deng.prepareWife)/ // undefined
console.log(deng.wife); //xiaozhang
deng.sayPrepareWife();
立即执行函数见:https://mp.youkuaiyun.com/mdeditor/90768332#
小测试
// 逗号运算符,把逗号后面的值返回
var a = (2, 3);
console.log(a);// 打印 3
var f = (
function f() {
return "1";
},
function g() {
return 2;
}
)();
console.log(typeof f);//Number
// 写出下面程序的执行结果
var x = 1;
if(function f() {}) {
x += typeof f;
}
console.log(x);// 1undefined
// 原因:if里面的方法声明,变成了表达式,
// 未经声明的变量,放到typeof里面不报错且返回undefined字符串