JavaScript闭包(笔记)

JavaScript闭包(笔记),第1张

JavaScript闭包(笔记)

什么是闭包?闭包是沟通内外部的桥梁

最浅显的理解:方法里面返回方法

//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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1298959.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存