如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?

我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。


当前回答

标签:猴子

在上面的例子中,outerFunction 被称为,其次称为 innerFunction. 请注意,outerVar 是如何向 innerFunction 提供的,通过正确警告 outerVar 的值来证明。

标签:猴子

referenceToInnerFunction 设置为 outerFunction(),它简单地返回一个参考到 innerFunction. 当 referenceToInnerFunction 被召回时,它返回 outerVar. 再次,如上所述,这表明 innerFunction 有访问 outerVar,一个变量 outerFunction. 此外,值得注意的是,它保留这个访问,即使 outerFunction 完成执行后。

警告:猴子警告:猴子警告

關閉的兩件事要注意:第一,關閉總是會有其內容功能的最後價值的存取。

函数外( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( )

其他回答

有些人非常接近得到简单的解释,然后变得复杂或保持抽象,击败目的,并无法显示一个非常简单的现实世界使用。

关闭有访问包含函数的变量 关闭在自己的内存空间中持久(因此对所有类型的 oop-y 实例物品都是有用的)

function sayHello(name) {
  var text = 'Hello ' + name; // Local variable
  console.log(text);
  var sayAlert = function () {
      alert(text);
  }
  return sayAlert;
}

sayHello(); 
/* This will write 'Hello undefined' to the console (in Chrome anyway), 
but will not alert though since it returns a function handle to nothing). 
Since no handle or reference is created, I imagine a good js engine would 
destroy/dispose of the internal sayAlert function once it completes. */

// Create a handle/reference/instance of sayHello() using the name 'Bob'
sayHelloBob = sayHello('Bob');
sayHelloBob();

// Create another handle or reference to sayHello with a different name
sayHelloGerry = sayHello('Gerry');
sayHelloGerry();

/* Now calling them again demonstrates that each handle or reference contains its own 
unique local variable memory space. They remain in memory 'forever' 
(or until your computer/browser explode) */
sayHelloBob();
sayHelloGerry();

这表明了你应该关于关闭的两个基本概念。

在简单的说法中,我有一个基本函数,我可以创建参考或操作,其中包含独特的数据,留在记忆参考中。我不需要每次我想说别人的名字,我都需要重写函数。

此分類上一篇

JavaScript 在两个阶段运行代码:

编辑阶段 // JavaScript 不是纯粹的语言解释 执行阶段

论点也存储在本地范围为f. 每当创建一个本地执行背景或范围时,它都包含对其母范围的参考指标. 所有变量访问都跟随这个词汇范围链以找到其价值. 如果一个变量不在本地范围中,它跟随链,并在其母范围中找到它. 这也是为什么一个本地变量在母范围中超越变量

什么是关闭?

它是函数与其范围链之间的暗示,永久的联系......函数定义(lambda)隐藏的范围参考,保持范围链(防止垃圾收集)。它被使用并复制为“外部环境参考”随时函数运行。

var data = "My Data!";
setTimeout(function() {
  console.log(data); // Prints "My Data!"
}, 3000);

明確的關閉

function makeAdder(n) {
  var inc = n;
  var sum = 0;
  return function add() {
    sum = sum + inc;
    return sum;
  };
}

var adder3 = makeAdder(3);

如果你想向一个六岁的孩子解释,那么你必须找到一些更简单的东西,没有代码。

只是告诉孩子他是“开放”的,这意味着他能够与其他人,他的朋友有关系。在某个时候,他有确定的朋友(我们可以知道他的朋友的名字),这是一个关闭。如果你拍照他和他的朋友,那么他是“关闭”相对他的友谊能力。

我倾向于通过好/坏的比较更好地学习,我喜欢看到工作代码跟随不工作的代码,有人可能会遇到,我把一个 jsFiddle 组合起来,它进行比较,并试图将差异推向我能找到的最简单的解释。

关闭是正确的:

console.log('CLOSURES DONE RIGHT');

var arr = [];

function createClosure(n) {
    return function () {
        return 'n = ' + n;
    }
}

for (var index = 0; index < 10; index++) {
    arr[index] = createClosure(index);
}

for (var index of arr) {
    console.log(arr[index]());
}

关闭错误:

console.log('CLOSURES DONE WRONG');

function createClosureArray() {
    var badArr = [];

    for (var index = 0; index < 10; index++) {
        badArr[index] = function () {
            return 'n = ' + index;
        };
    }
    return badArr;
}

var badArr = createClosureArray();

for (var index of badArr) {
    console.log(badArr[index]());
}

在上面的代码中,路径在创建ClosureArray()函数中移动,函数现在只会返回完成的路径,这在第一眼看起来更直观。

结果

函数和函数的外部范围(语法环境)的参考

函数 汽车(制造商,模型,年,颜色) { 返回 { 到String() { 返回 `${ 制造商} ${ 模型} (${ 年}, ${ 颜色})` } } 组车 = 新车(‘Aston Martin’,‘V8 Vantage’,‘2012’,‘Quantum Silver’) console.log(car.toString())

事件导向的编程

在下面的例子中,所有实施细节都隐藏在即时执行的函数表达式内。 函数标记和 toString 接近私人状态和函数他们需要完成工作。 关闭已使我们能够模块化和包容我们的代码。

例子1

这个例子表明,本地变量在关闭中没有复制:关闭保持了对原始变量的参考。

左边