(一)理解闭包
var a= 1;
function fn1(){
console.log(a);
var b = 234;
function fn2(){
console.log(b);
}
return fn2;
}
var result = fn1();
result();
闭包就是fn2,能够读取其他函数内部变量的函数。
闭包可以理解为一个定义在函数内部的函数。
闭包的作用:在外层的作用域下能访问到内层作用域中的作用
闭包最大的特点:它可以记住诞生的环境,比如fn2诞生的环境是fn1,所以在fn2中可以得到fn1中的内部变量
闭包的本质:函数内部和函数外部链接的桥梁
(二)闭包的用途
1。做一个计数器:读取函数的内部变量。这些变量始终在内存中。在使用闭包的时候要小心内存的泄漏。
function a() {
var start = 0;
function b() {
start++;
return start;
}
return b;
}
var inc = a();
console.log(inc());
console.log(inc());
console.log(inc());
inc = null; //释放当前变量
「注意」使用闭包使得函数的变量始终在内存中,内存的消耗很大,因此不能滥用闭包,否则会造成页面的性能问题。
在上面的第一个例子中,不能写成console.log(a()()),这样会一直打印0。因为调用的同时也清空了内存,一定要注意。
2。闭包能够封装对象的私有属性和方法。
function Person(name){
//私有的属性
var age;
//私有的方法
function setAge(n){
age = n;
}
function getAge(){
return age;
}
return {
name:name,
setAge:setAge,
getAge:getAge
}
}
var p1 = Person();
p1.setAge(20);
console.log(p1.getAge());
p1 = null;
「总结」:闭包需要三个条件:
函数嵌套。访问所在的作用域。在所在作用域外被调用
注意每个父函数调用完成,都会形成新的闭包,父函数中的变量会始终在内存中,相当于缓存。
(三)立即执行函数IIFE
()是一个表达式,跟在函数后面,表示调用函数。
立即执行函数:定义函数之后,立即调用该函数。这种函数称为立即执行函数。
「注意」如果function出现在行首,一律解释成函数声明语句。以下是两种常用的写法:
(function(){})();
(function(){}());
举例:计数器
//每次调用add,都会返回加1的数字(初始值为0)
var add = (function (){
//私有属性
var count = 0;
return function(){
return ++count;
}
})();
console.log(count);//会报错
console.log(add());
console.log(add());
console.log(add());
立即执行函数可以封装私有的属性,同时可以减少对全局变量的污染