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

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


当前回答

最好的方法是不断地解释这些概念:

console.log(x);
// undefined

var x = 42;
console.log(x);
// 42

现在,JavaScript知道X是什么意思。

x = 43;
console.log(x);
// 43

现在,X意味着别的东西。

范围

当您创建一个函数时,该函数为变量具有自己的“盒子”。

function A() {
  var x = 42;
}

console.log(x);

// undefined

var x = 42;

function A() {
  console.log(x);
}

// 42

在函数 A 中,您有“范围访问”到 x。

function A() {
  var x = 42;
}

function B() {
  console.log(x);
}

// undefined

function A() {

  var x = 42;

  function B() {
    console.log(x);
  }

}

// 42

功能

在JavaScript中,您通过称之为:

function A() {
  console.log(42);
}

A();

// 42

var a = function() {
  console.log(42);
};

变量现在意味着一个功能,你可以运行它。

a();
// 42

setTimeout(a, 1000);

在一秒钟(1000毫秒),函数一个点被称为:

// 42

现在,当你定义函数时,这些函数可以访问它们的外部目标。

var a = function() {

  var text = 'Hello!'

  var b = function() {
    console.log(text);
    // inside function `b`, you have access to `text`
  };

  // but you want to run `b` later, rather than right away
  setTimeout(b, 1000);

}

现在发生了什么?

// 'Hello!'

var c;

var a = function() {

  var text = 'Hello!'

  var b = function() {
    console.log(text);
    // inside function `b`, you have access to `text`
  };

  c = b;

}

// now we are out side of function `a`
// call `a` so the code inside `a` runs
a(); 

// now `c` has a value that is a function
// because what happened when `a` ran

// when you run `c`
c();

// 'Hello!'

您仍然可以在关闭范围内访问变量。

即使一个已经完成了运行,现在你正在运行C的外部。

在这里发生的事情被称为JavaScript中的“关闭”。

其他回答

关闭是一种功能,它可以从它所定义的环境中获取信息。

对于某些人来说,信息是创造时的环境价值;对于其他人来说,信息是创造时的环境变量。

一个关闭可以想象一个特殊的情况的全球变量 - 与一个私人副本创建仅为功能。

或者它可以被认为是一种方法,环境是对象的具体例子,其属性是环境中的变量。

前者(封闭作为环境)类似于后者,环境复制是前者中的每个函数转移的背景变量,例子变量在后者中形成一个背景变量。

因此,关闭是一种呼叫函数的方式,而无需明确地指定背景为参数或作为方法引用中的对象。

var closure = createclosure(varForClosure);
closure(param1);  // closure has access to whatever createclosure gave it access to,
                  // including the parameter storing varForClosure.

vs

var contextvar = varForClosure; // use a struct for storing more than one..
contextclosure(contextvar, param1);

vs

var contextobj = new contextclass(varForClosure);
contextobj->objclosure(param1);

默认情况下,JavaScript知道两种类型的目标:全球和本地。

var a = 1;

function b(x) {
    var c = 2;
    return x * c;
}

在上面的代码中,变量 a 和函数 b 可从代码中的任何地方(即全球)。变量 c 仅在 b 函数范围内可用(即本地)。

JavaScript 关闭有助于解决这个问题,通过将一个函数与一个背景:

function a(x) {
    return function b(y) {
        return x + y;
    }
}

在这里,函数 a 返回一个函数称为 b. 由于 b 在 a 中定义,它会自动访问在 a 中定义的任何内容,即 x 在此示例中。

var c = a(3);

var c = function b(y) {
    return 3 + y;
}

函数b 提醒 x = 3 在其背景下,因此:

var d = c(4);

关闭也可以用来限制全球宣布的变量和方法的范围:

(function () {
    var f = "Some message";
    alert(f);
})();

现在,有一个常见的JavaScript洞穴,在那里关闭可以帮助:

var a = new Array();

for (var i=0; i<2; i++) {
    a[i]= function(x) { return x + i ; }
}

a[0] = function (x) { return x + 0 ; }
a[1] = function (x) { return x + 1 ; }
a[2] = function (x) { return x + 2 ; }

a[0] = function (x) { return x + 2 ; }
a[1] = function (x) { return x + 2 ; }
a[2] = function (x) { return x + 2 ; }

var a = new Array();

for (var i=0; i<2; i++) {
    a[i]= function(tmp) {
        return function (x) { return x + tmp ; }
    } (i);
}

“关闭”这个词只是指能够在一个函数(六年:盒子)内访问关闭的物体(六年:物体)。即使函数(六年:盒子)不适用(六年:发送远程)。

我需要知道一个按钮被点击了多少次,每次第三点击都会做点什么。

考虑此选项

var element = document.getElementById('按钮'); element.addEventListener(“点击”,(函数() { // init 计算到 0 var 计算 = 0; 返回函数(e) { // <- 这个函数变成点击处理器计算++; // 并将保持访问上述 ` 计算` 如果(计算 === 3) { // 做点什么每第三次 console.log(“第三次是魅力!”); // 恢复 c

简单的单线关闭

//          _______________________Immediately invoked______________________
//         |                                                                |
//         |        Scope retained for use      ___Returned as the____      |
//         |       only by returned function   |    value of func     |     |
//         |             |            |        |                      |     |
//         v             v            v        v                      v     v
var func = (function() { var a = 'val'; return function() { alert(a); }; })();

func();  // Alerts "val"
func.a;  // Undefined

因此,在我们的主要例子中,计算变量包含在关闭室内,并始终可用于活动交易者,因此它保持其状态从点击到点击。

在那里你去;现在你正在完全包容这种行为。

关闭是当内部函数以某种方式为外部函数以外的任何范围提供时创建的。

例子:

var outer = function(params){ //Outer function defines a variable called params
    var inner = function(){ // Inner function has access to the params variable of the outer function
        return params;
    }
    return inner; //Return inner function exposing it to outer scope
},
myFunc = outer("myParams");
myFunc(); //Returns "myParams"