java 闭包方法
![](https://i-blog.csdnimg.cn/blog_migrate/944d4808c5bed2ffd1efff60d4db857e.png)
什么是封包?
闭包是一个内部函数,可以访问外部(封装)函数的变量-作用域链。 闭包具有三个作用域链:它可以访问自己的范围(在大括号之间定义的变量),可以访问外部函数的变量,并且可以访问全局变量
简单来说,就是函数内部的一个函数,它依赖于外部函数中的变量来工作。
理解概念的最好方法就是做到这一点。
因此,让我们在闭包上有一些例子。
function doSomeMath(){
var a=5;
var b=4;
var sum=a+b;
return sum;
}
var theResult = doSomeMath();
console.log("The result:", theResult);
我们在这里进行一些数学运算,设置三个变量,然后将一个变量添加到另一个变量中,然后返回总和。 现在,让我们仔细看看浏览器将如何正确处理此代码。 当我们在浏览器中运行脚本时。 它首先发现此功能doSomeMath,但对此没有任何作用。 然后,它进入此处并找到变量theResult,并看到已将doSomeMath分配给该变量。
这意味着它需要运行doSomeMath,因此它跳至函数,设置三个变量,执行数学运算,然后将结果放入sum变量中,然后返回sum变量。 然后将sum变量的内容放入Result中,并有效关闭doSomeMath函数,并丢弃其中的所有内容。 我们在Result中剩下的唯一值是9,这意味着如果我进入控制台,然后尝试调用A或B或求和,我什么也没得到。
![](https://i-blog.csdnimg.cn/blog_migrate/13ef5afcaa6097307bf26adf58b6853f.png)
那是因为它们位于函数doSomeMath的范围之内。 我们现在不在范围内,并且这些变量不存在。 到目前为止,这里没有新内容。 现在让我们稍微修改一下这个例子。
function doSomeMath(){
var a=5;
var b=4;
function multiply(){
var result = a*b;
return result;
}
return multiply;
}
var theResult = doSomeMath();
console.log("The result:", theResult);
如果我现在保存此内容,您将在控制台的此处看到,变量theResult现在保存了total函数与其所有内容的乘积。
![](https://i-blog.csdnimg.cn/blog_migrate/f291a3e24ba74c0cfd6282c3db79d4af.png)
如果我现在保存此内容,您将在控制台的此处看到,变量theResult现在保存了total函数与其所有内容的乘积。
![](https://i-blog.csdnimg.cn/blog_migrate/7503ebb26bd9bd7c195918b5f232584a.png)
这很奇怪,根据我们对功能如何工作的了解,这是行不通的。 我为什么这么说? 好吧,请考虑一秒钟。 浏览器从右上方读取? 因此,它首先找到函数doSomeMath,但对此没有执行任何操作。 然后,它跳到变量Result,并看到已将doSomeMath分配给它,因此它上升到顶部,并运行整个函数。 它设置了两个变量,注册了乘法函数,然后向下移动到底部并看到哦,我想返回乘法函数,但是我不想运行它,我只是想像返回它一样它是一个变量,所以我将这个乘法函数放在TheResult中,然后关闭其他所有内容。
因此从技术上讲,这意味着A和B应该不复存在,但是如果我们在控制台中查看,显然它不存在,显然它仍然存在。 这就是所谓的闭包。 发生的是,此内部函数乘法依赖于在外部函数中定义的变量。 而且浏览器足够聪明,可以理解哦,这些东西是相关的,因此,即使我们关闭了doSomeMath函数,我仍将保留这两个变量,以便乘法函数仍然可以使用它们。
那么为什么要具有此功能?
好吧,它有一些有趣的实际应用。 让我向您展示一个非常简单的示例。 我将清除所有代码,然后重新开始。 如果您曾经在CSS中使用过Ems,那么您会知道计算起来有些麻烦,尤其是如果您知道要查找的像素值是多少,然后必须弄清楚类似的Em价值将是。
Ems的诀窍是,如果您知道当前上下文的像素值,则可以只获取您要查找的像素值,比如说32个像素,然后将其除以当前上下文像素值,如果仅在整个浏览器中正常工作通常为16。所需像素值32的结果除以根像素值16可得到Em值。 使用闭包,我们可以创建一个函数来帮助我们生成这些数字。
首先,我将建立一个新函数,并将其命名为GiveMeEms。 此函数有一个参数(像素)。 这是我们要转换为Ems的像素值。 在函数内部,我们有一个名为baseValue的变量。 我将其设置为16,因为大多数浏览器的基本字体大小为16。 然后,我们建立了一个内部函数doTheMath。 在doTheMath内部,我们将简单地返回pixel / baseValue。
看到这里,我们要获取该pixels参数,并在内部函数中使用它,然后获取变量基值,并在内部函数中使用它。 最后关闭所有内容,我们返回doTheMath。 现在,我们可以设置一系列变量,调用giveMeEms和不同的像素大小,并获取返回值。 因此,我将设置var smallSize = GiveMeEms。
在这里,我将传递(12),所以我正在寻找等于12个像素的Em值。 然后var mediumSize = GiveMeEms(18),var largeSize = GiveMeEms(24)。 最后是var xlargeSize = GiveMeEms(32)。
然后,要在此处实际获得结果,我将创建console.log(“ Small size:”和smallSize)。 我只复制这些。 中,大,特大最后,我需要将小,中,大和超大变量作为函数运行。
function giveMeEms(pixels){
var baseValue = 16;
function doTheMath(){
return pixels/baseValue;
}
return doTheMath;
}
var smallSize = giveMeEms(12);
var mediumSize = giveMeEms(18);
var largeSize = giveMeEms(24);
var xlargeSize = giveMeEms(32);
console.log("Small Size", smallSize())
console.log("Medium Size", mediumSize())
console.log("Large Size", largeSize())
console.log("Extra Large Size", xlargeSize())
当我保存并在浏览器中运行它时,
![](https://i-blog.csdnimg.cn/blog_migrate/160e4f2d306874c498fb8b3743126ffd.png)
对于每种尺寸,我得到的Em尺寸分别为0.75、1.125、1.5和2。同样,这仅由于封闭而可能。 在这种情况下,这里的闭包既包含此变量的基值,又包含像素的值,即使从技术上讲,giveMeEms函数已经运行,并且当我们在此处调用它时,我们不应该能够获得这些值价值观。
JavaScript中的闭包是一个有趣的话题,这个特殊的兔子洞比我在这里向您展示的要深入得多。 为了更好地了解闭包的功能强大,可以在哪里使用它们以发挥自己的优势以及何时可能导致问题,您应该查看有关闭包的MDN文章。 它提供了许多示例,以及有关正在发生的事情的更多详细信息,并向您展示了如何在日常代码中使用它们。
嗨,我叫 Rahul Kumar Mandal 。 我是全栈开发人员。我写有关JavaScript,NodeJS和reactjs的文章。 并与所有人分享我的世界观,通过在 Twitter 或 Medium中 关注我,加入我的追求 。
希望您喜欢这篇有关JavaScript闭包的文章。
欢迎发表评论并喜欢这篇文章,以便其他人可以在Medium上轻松找到它!
并感谢您阅读本文,如果您喜欢它,然后与您的朋友和敌人分享。 我会写更多关于JavaScript的, 的NodeJS ,react.js陪在我身边相连。
翻译自: https://hackernoon.com/closures-in-javascript-learn-the-easy-way-7a7317ce2a07
java 闭包方法