Java教程

JavaScript 重中之重的难点————闭包

本文主要是介绍JavaScript 重中之重的难点————闭包,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
JavaScript 重中之重的难点————闭包

一、作用域链:

  首先推荐B站一个视频,视频从作用域链、生命周期、块级作用域、到闭包讲的十分全面:https://www.bilibili.com/video/BV1YJ411R7ap?p=3&spm_id_from=pageDriver&vd_source=452bb044f96afbbf26944f5c6904defd

  现在开始,了解闭包之前必须要了解明白JavaScript作用域的划分。

  1.作用域:变量和函数的可访问范围,控制着变量和函数的可见性与变量的作用范围。

  2.全局作用域:网页中所有脚本和函数均可使用。

   全局变量即拥有全局作用域的变量,即使页面没有调用使用,也不会被回收机制清除,而是继续存在于内存中,只有浏览器关闭时候才会清空。

  3.局部作用域:只能在定义的函数内使用。

          局部变量即在定义函数内可以调用使用的变量,函数调用结束之后就会清空,下次调用在重新开辟内存空间

  举一个例子:定义两个变量 一个全局a 一个局部b。

 

 

 

 

 

  可以根据结果看出,在全局环境中如果调用输出局部变量会报错:子用父可以,父用子不行。

  在举一个新例子:嵌套函数 更加深层次嵌套,如果想要输出b的累加

 

 

 

 

 

 

  根据结果可以清除看到,局部变量b每次都要重新开辟内存空间,之前的b就被回收删除了。

 

 

 

 

 

 

   那么现在想实现一次b的累加 如何做到,如果可以让b每次都不清空,保存在内存之中不动,跳过重新开辟内存这一步骤,是不是就可以完成累加。

  如果在全局中设定一个变量,用来存放xx()一直调用,那么回收机制就不会触发,也就不会重新开辟内存。

  而经过ax调用yy(),同级变量b并不会被清空销毁,而是同时保存在内存中。即这就是闭包。

 

 二、闭包:

  1.定义:闭包函数是声明在另一个函数内的函数,是被嵌套在父函数内部的子函数。

  而在《JS高级程序设计-第3版》中对闭包解释是:"闭包是指有权访问另外一个函数作用域中的变量的函数." 闭包函数可以访问[包裹其的函数]内的各种参数和变量,即便外部函数已经执行完毕。

  看不懂太乱对不对。那么就用人话解释一下。函数可以访问其他函数内的变量就称为闭包。

  上述例子当中,子函数yy() 可以访问父级函数当中变量b,即为闭包特性之一。

  2.闭包作用:

    • 使外部得以访问函数内部的变量;
    • 避免全局变量的使用,防止全局变量污染
    • 让某些关键变量得以常驻内存,免于被回收销毁

  3.闭包缺点:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

  4.闭包应用:使用场景 : 防抖、节流、函数套函数避免全局污染等。

三、闭包应用场景:

  1.获取区间:例如在一串数组中获取一个区间之间的数字。

 

 

  其原理正是闭包原理。内部子函数可以调用外部父函数between内部的变量a和b。也可以应用到商品价格区间等。

  2.防抖:防抖是经常出现在js动画中的概念,好多萌新都不了解什么是防抖。其实顾名思义防止抖动。那么为什么动画会出现抖动?

  假设现在制作一个动画,一个按钮点击之后就缓慢向右移动。代码如下,可以很简单的实现效果

 

  但现在存在一个问题,如果点击多次按钮,就会出现按钮抖动(原谅我截图没办法体现抖动的状态。)就好像花屏一样。那么为什么会出现这种情况?

  首先,当你点击一次按钮,触发了事件之后,已经在内存当中开辟了一块区域让你存放。但是当你点击第二次,由于 left 是局部,所以还会开辟第二块区域。结果每次点击都产生新的left 就会造成抖动效果。

 

 

  那么如何避免,就像上面提到如何累加的案例一样,如果让left不在重新产生,而是一直存放在内存中,就可以完美解决了。

  最简单的办法就是,将left设置为全局属性,这样就一直存放在内存中。

 

 

  随之而来就出现另一个问题,当你再次连续点击按钮,虽然不会出现抖动效果,但是会产生按钮加速向前的效果。这是因为每次点击按钮,都产生一个定时器,而left 变成全局之后,定时器就变成了一个类似于叠加的效果,所以导致动画加速。那么就要将定时器设定为,只有第一次才会触发,直到动画结束。添加一个全局变量,在通过if判断。

 

 

   但是变量都设定为全局会导致,全局变量污染,加剧内存负担。所以就可以将left 放入 判断里面。

 

 四、总结:

  讲的可能不是特别全面,个人自身也是萌新小白,只能慢慢摸索去学,希望大家都比昨天的自己进步一点。

这篇关于JavaScript 重中之重的难点————闭包的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!