js中的闭包
闭包的概念:利用函数的嵌套,实现将第一层函数中的局部变量,可以在第一层函数外部修改的过程,叫闭包
闭包的形成环境:
1.函数的嵌套
2.内部函数使用外部函数中的变量
3.将内部函数返回,在外部函数的外部,接收返回值,执行(相当于执行了内部函数)
闭包的特点:
1.解决掉所有的全局变量,节省内存空间
2.可以在函数外部,修改函数内部的变量
3.相对于局部变量来说,浪费了内存
闭包并不是一种固定写法,而是一种场景,只要满足了上述形成环境的三个条件,就是闭包
// 函数在定义时,存在一个位置,当前函数的定义作用域
// 函数在执行时,存在一个位置,当前函数的执行作用域
// 定义作用域和执行作用域,都不是当前函数自身内部,而是当前函数所处的位置
function box(){
function fn(){}
fn();
// fn的执行作用域,是box的局部作用域
}
// box的定义作用域,是全局作用域
// fn的定义作用域,是box的局部作用域
box();
// box的执行作用域,是全局作用域
fn(); //执行不了
function fun(){
box();
// box的执行作用域,是fun的局部作用域
}
function box(){
function fn(){}
return fn;
}
// 在box中返回了一个函数,返回值被f变量保存,因为函数也是对象,简单赋值属于浅拷贝,那么其实当前的f就是box中返回的那个函数的一个引用。如果将f作为函数执行了,相当于执行了box返回的那个函数的引用,其实就是执行了box里面的函数
var f = box();
f();
// 当前变量f,其实就是box内部的fn,它的执行作用域,就变成了全局
// 函数的定义作用域,是固定的,写在哪就是哪
// 函数的执行作用域,是可变的,在哪执行就是哪
// 函数在执行时,可以拿到当前函数所在定义作用域中的所有数据
// 函数形成闭包时:
function box(){
var a = 10;
function fn(){
a++;
console.log(a);
}
return fn;
}
var f = box();
// 执行内部函数f,可以修改外部函数box的私有变量
f(); // 11
f(); // 12
// 闭包的应用场景:
// 1.循环中的事件,事件处理函数中使用了循环每次的计数器
// 2.给某些系统默认的回调函数,传参(给计时器的回调函数,传参)
function fn(a){
return function(){
console.log(a);
};
}
setTimeout(fn("world"), 1000);
// 3.处理掉全局变量,只要开启新文件,新功能,最好上手就是一个匿名函数,简易闭包
// 4.事件委托的封装,也会利用到闭包