JavaScript词汇范围和闭包



JavaScript环境翻译,词法范围和闭包

让我们谈谈环境。 我们巨大的星球是万能的。 在建造新的化工厂期间,最好将其隔离,以使所有内部过程都不会脱离边界。 可以说该植物的环境和微气候与外部环境隔离。

该程序的安排与此类似。 您在外部创建的内容(外部函数,条件语句,循环和其他块)是一个外部全局环境。



恒定agemultiplier函数和result变量在外部环境中。 这些组件具有全球范围。 范围是组件可用的区域。

在这种情况下, xmultiplier函数内部的常数。 由于它位于代码块内部,因此它是局部常量,而不是全局常量。 它仅在函数内部可见,而在外部则不可见-它的作用域是局部的。

multiplier函数具有本地作用域中的另一个组件-这是num参数。 定义它比常量或变量要困难得多,但是它的行为大致类似于局部变量。

我们没有x外部访问权限-它似乎不存在:



在未定义x的全局环境中, console.log称为x 。 结果,我们得到了ReferenceError。

我们可以全局设置x



我们有一个具有已知值的全局x ,但是multiplier函数中的局部x仍然仅从内部可见。 这些x没有以任何方式连接-它们处于不同的环境中。 尽管名字相同,但它们没有混合在一起。

花括号中的任何代码块都成为本地环境。 这是使用if的示例:



whilefor循环会发生相同的情况。

因此本地意味着从外部看不见。 也就是说,全局在任何地方都可见,甚至在对象内部也可见? 是的



全局变量a已在changer函数内部更改。 该函数仅在调用时才生效,而不是在定义时才生效,因此最初为a=0 ,并且在调用时, changer取值为1

容易屈服于诱惑,将所有事物放到全球范围内,而忽略了各个环境的所有复杂性-但这是一个可怕的想法。 全局变量使您的代码极其脆弱,任何元素都可以在任何时间破坏任何其他元素。 因此,请勿使用全局作用域并将所有内容保留在原位。

第二部分 词汇范围


看一下这个程序:



multiplier函数返回乘法ab的结果。 a内部提供的,而b不是。

尝试执行a*b乘法运算时,JavaScript将查找ab的值。 他开始在内部搜索,然后出门,一个接一个地研究一个区域,直到发现自己要找的东西,或者不知道这是不可能找到的。

因此,在此示例中,JavaScript开始在局部区域内- multiplier函数内寻找。 他立即找到值并转到bb他在当地环境中找不到,所以他超越了它。 在那里,他得知b10 。 因此a*b变成5*10 ,然后变成50

这段代码可以在另一个函数中,也可以在另一个函数中。 如果没有在第一层中找到b ,JavaScript将继续搜索新层和新层中的所有内容。

请注意, a=7不会以任何方式影响计算结果:a的值位于内部,因此,外部a不起作用。

这称为词汇作用域。 任何组件的范围都取决于该组件在代码中的位置,并且嵌套块可以访问外部区域。

第三部分 短路


大多数编程语言都支持环境和范围,并且此机制允许引入闭包。 闭包本质上是一种“记忆”内部使用的外部实体的功能。

在继续之前,让我们回顾一下如何创建和使用函数:



f是一个非常无用的函数,始终返回0 。 该集合包括两个部分-常量和函数本身。

重要的是要记住,这些是独立的组件。 第一个分量是称为f的常数。 它的值可以是数字或字符串值。 在这种情况下,该值是一个函数。

在过去的课程中,我们引用了一个类比:常量就像一张纸,一侧有一个名称,而另一侧是一个值。 因此, f是一张纸,其中f写在一侧,而对功能的描述则写在另一侧。

调用此函数时:



根据一张纸上的描述创建一个新的“盒子”。

回到瓶盖。 这是示例代码。



createPrinter函数创建一个name常量,然后创建一个名为printName的函数。 两者都是createPrinter函数的本地函数,并且仅在函数内部可用。

printName本身printName本地组件,但是可以访问在其中创建它的作用域以及在外部环境中为该常量分配name权限。

createPrinter函数返回printName函数。 回想一下,函数定义是对运行函数的描述;它们只是数据元素,如数字或链。 因此,我们可以像返回数字一样返回函数的定义。

在外部范围中,我们创建常量myPrinter并将其返回值设置为createPrinter 。 返回一个函数,因此myPrinter也成为一个函数。 当您调用它时, King将会出现在屏幕上。

有趣的是: name常量是在createPrinter函数内部创建的。 该函数被调用并执行。 如您所知,当一个函数完成工作时,它就不复存在了。 魔术框和所有内容一起消失。

但是他返回了另一个函数,该函数以某种方式记住了常量name 。 因此,当调用myPrinter我们得到了myPrinter函数记住的值,尽管该区域不再存在。

createPrinter返回的函数称为闭包。 闭包是函数和定义它的环境的组合。 该功能本身“封闭”了范围内收到的某些信息。

这可能看起来像是一个怪异的JavaScript怪癖,但是明智地使用闭包可以使您的代码更令人愉悦,清晰和易读。 返回函数的原理(例如返回数字和字符串值)为您提供了更大的操作自由度。

Source: https://habr.com/ru/post/zh-CN460861/


All Articles