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

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


当前回答

我知道已经有很多解决方案,但我猜这个小而简单的脚本可以有用来证明这个概念:

// makeSequencer will return a "sequencer" function
var makeSequencer = function() {
    var _count = 0; // not accessible outside this function
    var sequencer = function () {
        return _count++;
    }
    return sequencer;
}

var fnext = makeSequencer();
var v0 = fnext();     // v0 = 0;
var v1 = fnext();     // v1 = 1;
var vz = fnext._count // vz = undefined

其他回答

我只是将它们指向Mozilla关闭页面,这是我发现的关闭基础和实用使用的最佳,最简短和简单的解释,强烈建议任何人学习JavaScript。

而且是的,我甚至会推荐给一个6岁的人 - 如果6岁的人正在学习关闭,那么他们准备好理解文章中提供的简短和简单的解释。

第一点的例子 由 dlaliberte:

关闭不只是在您返回内部函数时创建。 事实上,关闭函数根本不需要返回. 您可以将内部函数归咎于外部范围中的变量,或者将其作为一个论点转移到另一个函数,在那里它可以立即使用。

var i;
function foo(x) {
    var tmp = 3;
    i = function (y) {
        console.log(x + y + (++tmp));
    }
}
foo(2);
i(3);

查找描述的解释:如何在场景背后的JavaScript关闭工作。

文章解释了范围对象(或LexicalEnvironments)如何分配并以直观的方式使用。

"use strict";

var foo = 1;
var bar = 2;

function myFunc() {
  //-- Define local-to-function variables
  var a = 1;
  var b = 2;
  var foo = 3;
}

//-- And then, call it:
myFunc();

在执行顶级代码时,我们有以下范围对象的安排:

此分類上一篇

当 myFunc() 被召唤时,我们有以下范围链:

此分類上一篇

了解范围对象是如何创建,使用和删除,这是一个关键,有一个大图像,并了解如何在盖子下工作关闭。

请参见上述文章,详细信息。

关闭是通过内部函数可以提到在其外部关闭函数中存在的变量,其母函数已经结束后。

// A function that generates a new function for adding numbers.
function addGenerator( num ) {
    // Return a simple function for adding two numbers
    // with the first number borrowed from the generator
    return function( toAdd ) {
        return num + toAdd
    };
}

// addFive now contains a function that takes one argument,
// adds five to it, and returns the resulting number.
var addFive = addGenerator( 5 );
// We can see here that the result of the addFive function is 9,
// when passed an argument of 4.
alert( addFive( 4 ) == 9 );

在JavaScript中,关闭是令人惊叹和独特的,其中变量或论点可用于内部功能,即使外部功能已返回后,它们也会活着。

function getFullName(a, b) {
  return a + b;
}

function makeFullName(fn) {

  return function(firstName) {

    return function(secondName) {

      return fn(firstName, secondName);

    }
  }
}

makeFullName(getFullName)("Stack")("overflow"); // Stackoverflow