栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

JavaScript闭包与匿名函数

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaScript闭包与匿名函数

编者按:
在Javascript中所有的功能都关闭在这个解释后但是,我们只对确定这些功能的子集感兴趣,这从理论上讲是很[有趣的。此后,除非另有说明,否则对闭包一词的任何引用都将指代此功能子集。

闭包的简单说明:

  1. 发挥作用。我们称它为F。
  2. 列出F的所有变量。
  3. 变量可以有两种类型:
    1. 局部变量(绑定变量)
    2. 非局部变量(自由变量)
  4. 如果F没有自由变量,则它不能是闭包。
  5. 如果F具有任何自由变量(在F 父范围中定义),则:
    1. 必须有其中的F只有一个父范围 一个 自由变量绑定。
    2. 如果从 该* 父作用域之外 引用 F ,则它将成为 自由变量的闭包。 ***
    3. 自由变量称为闭包F的升值。

现在,让我们用它来找出谁使用闭包,谁不使用闭包(为便于说明,我将函数命名为):

情况1:您朋友的程序

for (var i = 0; i < 10; i++) {    (function f() {        var i2 = i;        setTimeout(function g() { console.log(i2);        }, 1000);    })();}

在以上程序中,有两个功能:

f
g
。让我们看看它们是否为闭包:

对于

f

  1. 列出变量:
    1. i2
      局部 变量。
    2. i
      是一个 自由 变量。
    3. setTimeout
      是一个 自由 变量。
    4. g
      局部 变量。
    5. console
      是一个 自由 变量。
  2. 查找每个自由变量绑定到的父范围:
    1. i
      绑定 到了全球范围。
    2. setTimeout
      绑定 到了全球范围。
    3. console
      绑定 到了全球范围。
  3. 该功能在哪个范围内 引用 ?在 全球范围内
    1. 因此
      i
      没有 关闭了 通过
      f
    2. 因此
      setTimeout
      没有 关闭了 通过
      f
    3. 因此
      console
      没有 关闭了 通过
      f

因此,该功能

f
不是闭包。

对于

g

  1. 列出变量:
    1. console
      是一个 自由 变量。
    2. i2
      是一个 自由 变量。
  2. 查找每个自由变量绑定到的父范围:
    1. console
      绑定 到了全球范围。
    2. i2
      绑定 到的范围
      f
  3. 该功能在哪个范围内 引用 ?的 范围
    setTimeout
    1. 因此
      console
      没有 关闭了 通过
      g
    2. 因此
      i2
      封闭在 通过
      g

因此,该功能

g
是用于自由变量的封闭
i2
(这是用于的upvalue
g
它的 引用 从内
setTimeout

对您不利: 您的朋友正在使用闭包。内部函数是一个闭包。

情况2:您的程序

for (var i = 0; i < 10; i++) {    setTimeout((function f(i2) {        return function g() { console.log(i2);        };    })(i), 1000);}

在以上程序中,有两个功能:

f
g
。让我们看看它们是否为闭包:

对于

f

  1. 列出变量:
    1. i2
      局部 变量。
    2. g
      局部 变量。
    3. console
      是一个 自由 变量。
  2. 查找每个自由变量绑定到的父范围:
    1. console
      绑定 到了全球范围。
  3. 该功能在哪个范围内 引用 ?在 全球范围内
    1. 因此
      console
      没有 关闭了 通过
      f

因此,该功能

f
不是闭包。

对于

g

  1. 列出变量:
    1. console
      是一个 自由 变量。
    2. i2
      是一个 自由 变量。
  2. 查找每个自由变量绑定到的父范围:
    1. console
      绑定 到了全球范围。
    2. i2
      绑定 到的范围
      f
  3. 该功能在哪个范围内 引用 ?的 范围
    setTimeout
    1. 因此
      console
      没有 关闭了 通过
      g
    2. 因此
      i2
      封闭在 通过
      g

因此,该功能

g
是用于自由变量的封闭
i2
(这是用于的upvalue
g
它的 引用 从内
setTimeout

对您有好处: 您正在使用闭包。内部函数是一个闭包。

因此,您和您的朋友都在使用闭包。别吵了 我希望我清除了闭包的概念以及如何为你们两个人识别它们。

编辑: 关于为什么所有函数都关闭的简单说明(点数@Peter):

首先让我们考虑以下程序(它是control):

lexicalScope();function lexicalScope() {    var message = "This is the control. You should be able to see this message being alerted.";    regularFunction();    function regularFunction() {        alert(eval("message"));    }}
  1. 我们知道,无论
    lexicalScope
    regularFunction
    不封闭 ,从上面的定义
  2. 当我们执行程序时, 我们希望
    message
    收到警告, 因为
    regularFunction
    它不是闭包的(即它可以访问其父作用域中的 所有 变量-包括
    message
    )。
  3. 当我们执行程序时, 我们观察
    message
    确实确实有警报。

接下来让我们考虑以下程序(这是替代程序):

var closureFunction = lexicalScope();closureFunction();function lexicalScope() {    var message = "This is the alternative. If you see this message being alerted then in means that every function in Javascript is a closure.";    return function closureFunction() {        alert(eval("message"));    };}
  1. 我们知道,这只是 上述定义*
    closureFunction
    的闭包。
    *
  2. 当我们执行程序时, 我们希望*
    message
    不会 因为
    closureFunction
    闭包而收到警告(即,在 创建函数时, 它只能访问其所有 非局部变量 (请参见此答案)-不包括)。
    *
    message
  3. 当我们执行程序时, 我们观察
    message
    实际上正在被警告。

我们从中得出什么呢?

  1. Javascript解释器对待闭包的方式与对待其他函数的方式没有区别。
  2. 每个功能都带有其作用域链。闭包没有 单独的 引用环境。
  3. 闭包就像其他函数一样。当在它们所属的范围 之外* 的范围中 引用 它们时,我们只称它们为闭包, 因为 这是一个有趣的情况。 ***


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/614626.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号