JavaScript笔记 “作用域和闭包”

前言

其实这篇文章算是我写的第一篇。因为之前的学习太混乱,导致很多东西掌握不牢,现在系统的学习并且把遇到的问题和个人的见解记录下来,方便自己复习,要是顺便能帮到大家就更好了。

能力不足,水平有限,如果写的有问题还希望大家指出问题,我好及时纠正。


JavaScript之闭包

概念

先举例,因为JavaScript的变量的读取是逐层向外查找的所以可以写出这样的代码:

function foo () {
    var ark = 1;
    return function bar () {
        ark++;
        console.log(ark);
    }
}

var x = foo();
x();  //  ark = 2
x();  //  ark = 3

可以看出foo()这个函数中有一个局部变量ark = 1,并且返回了一个函数bar(),因为bar()是定义在foo()中的,所以可以访问变量ark,然后把foo()的返回值赋给变量x,这是x是个函数,接着调用x两次,可以发现ark本来是1,但是两次调用后ark在一直累加。其实这就是简单闭包。
个人理解就是一个函数可以访问一个自由变量就构成闭包了。

这里备注!如果变量ark定义在bar()中,foo()是不能访问的,而且如果你想要一个在函数中声明一个局部变量一定要var xxx = xxx!如果只是xxx = xxx,xxx会相当于一个全局变量。


从词法作用域理解为什么

但是上面闭包的例子成功的保存了ark这个变量,我的理解这个原因是因为,foo()中返回的函数bar()最后一次执行时foo()相当于还是在被间接的调用,所以foo()中的信息一直没有被销毁,而是存在内存中(所以个人觉得不能滥用)。这样ark的每次叠加就被记录了下来。


有什么用

目前我觉得闭包的用处就是可以对一个变量持续的操作,而这个变量不一定需要是全局变量(不用污染全局变量),比如在冴羽的博客中的跟着underscore学防抖这篇中有个需求是实现降低高频操作的频率,比如监听鼠标的移动,每次移动计数器加一,但是如果每次移动的操作很复杂,由于触发频率太高,可能就会有性能上的问题。那么我们可以使用setTimeout来延缓执行,如果这一次触发就重置这个定时器,这样在我们设置的毫秒数内就不会重复执行操作,引用这篇文章的例子理解闭包的用处。

function debounce(func, wait) {
    var timeout;
    return function () {
        clearTimeout(timeout)
        timeout = setTimeout(func, wait);
    }
}

参数func是事件触发时要执行的方法,wait是等待的毫秒数。
为什么用闭包呢?因为如果在wait的时间内事件再一次被触发我们要clearTimeout,不这样的话只是把所有操作延后了一个wait而已,该执行多少次还是多少次,这就没有达成我们降低频率的要求,所以上一个timeout我们要给他保存下来,好在超过频率时给他清理掉,重新设置。这样我们就要对timeout持续操作,所以使用闭包。之后比较理解了高级用法的时候还会再来补充。


最后

如果有想深入理解的小伙伴可以去看看冴羽的博客。我觉得写的很好,很专业。要是大家有什么好的教程博客也可以推荐给我,我会十分感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值