如何向某人解释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中,关闭是令人惊叹和独特的,其中变量或论点可用于内部功能,即使外部功能已返回后,它们也会活着。

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

const makePlus = 函数(x) { 返回函数(y) { 返回 x + y; } const plus5 = makePlus(5); console.log(plus5(3));

如果JavaScript不知道关闭,会发生什么? 只需由其方法体(基本上是函数通话所做的事情)在最后一行中取代通话,你会得到:

console.log(x + 3);

现在, x 的定义在哪里? 我们没有在当前范围内定义它. 唯一的解决方案是让 plus5 携带其范围(或更好地说,其父母范围)。

关闭是一种内部函数,可以访问外部(关闭)函数的变量 - 范围链. 关闭有三个范围链:它可以访问自己的范围(在曲线手臂之间定义的变量),它可以访问外部函数的变量,并且可以访问全球变量。

function showName(firstName, lastName) {
      var nameIntro = "Your name is ";
      // this inner function has access to the outer function's variables, including the parameter
      function makeFullName() {
          return nameIntro + firstName + " " + lastName;
      }
      return makeFullName();
  }

  console.log(showName("Michael", "Jackson")); // Your name is Michael Jackson

此外,这是一个经典的关闭方式在jQuery,每个JavaScript和jQuery开发人员使用它很多:

$(function() {
    var selections = [];
    $(".niners").click(function() { // this closure has access to the selections variable
        selections.push(this.prop("name")); // update the selections variable in the outer function's scope
    });
});

实用关闭

//javascript function makeSizer(size) { return function() { document.body.style.fontSize = size + 'px'; } var size12 = makeSizer(12); var size14 = makeSizer(14); var size16 = makeSizer(16); document.getElementById('size-12').onclick = size12; document.getElementById('size-14').onclick = size14; document.getElementById('size-16').onclick = size16; /*css*/ body {字体

JavaScript 的关闭与 scopes 的概念有关。

在 es6 之前,没有区块级范围,只有 JS 的功能级范围。

也就是说,每当需要区块级范围时,我们都需要将其插入一个函数中。

看看这个简单而有趣的例子,关闭如何解决这个问题在ES5

// 让我们说我们只能使用一个传统的路径,而不是forEach为(var i = 0; i < 10; i++) { setTimeout(函数() { console.log('没有关闭访问指数 - '+ i) }) ) } // 这将打印10次“访问指数 - 10”,这是不正确的 /** 预计输出是访问指数 - 0 访问指数 - 1.. 访问指数 - 9 **/ // 我们可以通过使用 cl 解决它

注:这可以轻松地通过使用 es6 取代 var 来解决,因为它创造了语法范围。


简而言之,在 JS 中关闭仅仅是访问功能范围。

關閉的觀點:

封面可以与一本书,一本书标记,一本书架上进行比较。

这类似于关闭,书是外部函数,页面是你的内部函数,从外部函数返回,书标是你的页面的参考,故事的背景是你需要保存的语法范围。

代码例子:

function book() {
   var pages = [....]; //array of pages in your book
   var bookMarkedPage = 20; //bookmarked page number
   function getPage(){
       return pages[bookMarkedPage];
   }
   return getPage;
}

var myBook = book(),
    myPage = myBook.getPage();

要考虑的几点:

点1:书架,就像函数板有有限的空间一样,所以要明智地使用它。

点2:想想事实,如果你只想跟踪一个页面时,你是否需要坚持整个书,你可以释放部分记忆,而不是在关闭回来时存储所有页面。