js 闭包传参_JavaScript 闭包图文解析

什么是闭包?

我们来看看 MDN 上的解释:A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。

クロージャは、関数と、その関数が宣言されたレキシカル環境の組み合わせです。

是不是感觉奇怪的概念又增加了?没关系,我们可以用一种通俗的方式来理解:

下面我们来看一个例子:一个闭包的例子

引用传递与值传递

通过上面的通俗解释,我们已经大概了解什么是闭包了。但是有的小朋友可能还不是很懂什么叫做 “变量的引用” 。接下来,我们通过一个类比情景来理解引用传递与值传递的区别。

情景:又到月末了,可是 22娘 的总结报告还没写,怎么办呢?22娘 想起了自己的好兄弟 33娘,她那么勤奋,一定早就写好了。于是 22娘 恳求 33娘 把她的总结报告给自己发一份,然后自己只需要在 33娘 的版本基础上进行修改就好了。

而 33娘 有两种方法来给 22娘 分享自己的总结报告:方法1

33娘 将自己电脑上的报告复制了一份,发给了 22娘。此时 22娘 在自己的电脑上修改了 33娘 报告的副本作为自己的报告,而 33娘 电脑上原本的报告并不受影响。这样,两人都及时上交了报告,皆大欢喜。方法2

33娘 将自己电脑的远程访问权限授予 22娘。此时 22娘 虽然也是在自己的电脑上操作,但实际上是修改了 33娘 电脑上的报告原件。结果 33娘 被 22娘 坑惨了。上面的 方法1 是值传递,修改副本不会导致原件的改变;修改原件也不会影响副本。

上面的 方法2 是引用传递,修改引用会导致原件改变;修改原件也会导致引用改变。

小朋友们,这下明白了吗?

实验1:一个简单的闭包

现在,然我们回头看看前面的例子,你能猜出函数执行后 a 和 b 的值吗?实验1

这个例子还是相当简单的,相信大家都能得出正确答案:输出

实验2:引用的性质

现在我们对上面的例子稍作改动,在 outer 函数内加几行代码:实验2

这一次结果又会如何呢?回想一下刚才讲过的 “引用”,你有答案了吗?输出

分析:当 inner 函数被创建时,它拿到了 a 和 b 的引用。而后 a 和 b 被 outer 函数修改了,所以 inner 函数拿到的引用的值也随之改变了。

实验3:函数参数的传递

为了给下面的内容做铺垫,我们先来了解一下函数参数的传递。在 JavaScript 中,函数的参数全部是值传递。不信,你来做做下面的例子。实验3

输出

果然,a 和 b 的值都没有被函数改变,因为在函数内部操作的其实是我们传入参数的副本,参数原本的值本不会被改变。

实验4:写了题目不就剧透了吗

有了前面的铺垫,在这里要出题考考大家了。如果我想让 实验2 中的 a 和 b 不被 outer 函数改变,该怎么做呢?动动小脑瓜

聪明的你应该已经想到了,利用函数传参将引用传递改为值传递!

下面是参考代码:实验4

输出

分析:inner 函数获取到的是 a 和 b 的副本的引用。改变原件不会影响副本,自然也就不会影响副本的引用。

块作用域内的闭包

前面我们讲的都是函数作用域内的闭包,下面我们来看一个块作用域内闭包的例子:for 语句块作用域内的闭包

输出

特别要注意的是,循环变量一定要用 let 来声明。因为 var 声明的变量是没有块作用域的,如果用 var 来声明,它就会被提升为全局变量,从而在循环中被不断被重新赋值,导致函数获取的引用值被改变。用 var 来声明变量;警告信息:值可变的变量在闭包中被访问到

输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值