什么是闭包?闭包是沟通内外部的桥梁
最浅显的理解:方法里面返回方法
//eg:最简单的闭包
function func1() {
let a = 'aaa'
return function () {
return a;
}
}
console.log(func1())//查看返回的内容,发现是个函数
let s= func1()()//调用返回的函数
console.log(s);//打印返回的值
打印的内容
想要了解闭包,先了解作用域链
作用域链(就近原则)
let name = '小米'
function func3(){
// let name = '小兰'
function func4(){
// let name = '小白'
console.log(name);
}
func4()
}
func3()
作用域链 就近原则,他会找最近的找到直接输出,找不到继续往上找,知道找到为,如上面的例子,输出的是”小白“,如果注释了let name = ‘小白’,就往上找,输出的是”小兰“
延长变量的生命周期闭包存在的意义
正常情况下,定义在函数内的变量,外部是无法访问的,通过闭包的返回值就可以拿到。这里还不是太能体现延迟生命周期这一点,先理解下为何在外部无法访问内部的变量。(有人可能已经意识到了,局部变量,外面当然访问不了了,是这个没错,我们从底层看下他的运行机制)
在全局变量和局部变量上都给他打上断点
发现代码运行到 let a= ‘小米’ 时,在Script处可以看到a变量,走到这里为什么是undefined呢,那是因为代码到这里停了,只是声明了变量a,但没有赋值,所以为undefined(记住所有的变量先声明了再赋值的,而声明却没赋值都是undefined)接着继续走,
代码运行到let b='小梦’时,会发现,局部变量b的位置是在Local(翻译过来就是局部的意思)里的,而不是在script里面,代码继续走
到了发现问题没,局部变量b不见了,只剩下了全局变量a,这里就要说到js的执行机制了,在js运行的时候,他会生成一个临时的变量对象AO(Activive Object),AO?这时啥,有兴趣的朋友可以去了解下,在这里你只需要知道,代码执行时,所有的局部变量和方法都会存储到这个AO对象里面,全局变量不会存在这里,当你调用的方法执行完后,这个临时变量对象就会被回收(注销),所有你是无法访问局部变量的。
了解了这个再回来看闭包这个东西接下来就好理解了,为何他是沟通内外的桥梁,因为通过闭包能访问函数里的局部变量,废话不多说,上代码
let bb = "小红"
function outer (){
let aa = '111';
let bb = '222';
return function inter(){
return aa
}
}
function func5(){
let getInterData = outer();
console.log(getInterData)
console.dir(getInterData)
}
func5()
执行代码的结果
打印发现,他返回的是个函数,没给你返回 变量aa的值,通过dir查看的结构发现什么没,aa的值在Scopes里面的Cloure(闭包)里,看到这个不知大家有没有理解延长变量的生命周期这个特性了呢,除了aa变量,全局变量也能在Scopes里面看到,从这里就能看出为何不建议去定义全局变量,第一全局变量不会被回收,会一直存在,第二全局变量会污染局部变量。
闭包会常驻内存,可以通过手动回收闭包的变量,使用时慎用。
创建私有变量作用域不知小伙伴们有没有了解过vue2,有没有发现vue2中的data的结构很熟悉,没错,他就是个闭包
vue2的data结构
这么做的好处是,他让每个页面的数据都独立起来,不受其他页面的影响。
举个直观的例子,我们通过闭包写个计数器
给他返回三个方法,加1,减1,和查看当前的值
function makeCounter(){
let num = 0;
function changeNum(val){
num += val;
}
return {
add:function(){
changeNum(1);
},
reduce:function(){
changeNum(-1);
},
lookNum:function(){
return num;
}
}
}
let counter1 = makeCounter();
let counter2 = makeCounter();
console.log('counter1',counter1.lookNum());
console.log('counter2',counter2.lookNum());
counter1.add();
counter1.add();
counter2.reduce();
console.log('counter1',counter1.lookNum());
console.log('counter2',counter2.lookNum());
执行返回结果
我们通过同一个makeCounter()方法创建了2个变量,分别对其进行不同的 *** 作,有没有发现返回的值是不一样的,一个加了2,一个减了1
也就是说通过闭包创建变量是互不干扰的,各玩各的,每个变量都有自己独立的空间,即便是同个爹,生出的儿子都是独立的,是不一样的。
通过这个例子就能很直观的看到,闭包能创建私有变量作用域。
这个我学闭包时做的笔记,如有出错请各位大佬不吝啬指点一二(手动狗头)。
学习的视频链接:https://www.bilibili.com/video/BV1G3411s7pp?p=3&spm_id_from=pageDriver
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)