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

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


当前回答

因为所有这些外部变量,由一个经文所指的函数,实际上是其经文所关闭的函数链中的本地变量(全球变量可以假设是某种根函数的本地变量),并且每个函数的单一执行都会产生其本地变量的新例子,因此,每个函数的执行都会返回(或以其他方式转换)。

此外,必须明白,JavaScript中的本地变量不是在滑板框中创建的,而是在滑板上,只有当没有人提到它们时才会被摧毁。当一个函数返回时,其本地变量的参考会减少,但如果在当前执行期间,它们成为关闭的一部分,并且仍然被其经文所定义的函数所提到。

一个例子:

function foo (initValue) {
   //This variable is not destroyed when the foo function exits.
   //It is 'captured' by the two nested functions returned below.
   var value = initValue;

   //Note that the two returned functions are created right now.
   //If the foo function is called again, it will return
   //new functions referencing a different 'value' variable.
   return {
       getValue: function () { return value; },
       setValue: function (newValue) { value = newValue; }
   }
}

function bar () {
    //foo sets its local variable 'value' to 5 and returns an object with
    //two functions still referencing that local variable
    var obj = foo(5);

    //Extracting functions just to show that no 'this' is involved here
    var getValue = obj.getValue;
    var setValue = obj.setValue;

    alert(getValue()); //Displays 5
    setValue(10);
    alert(getValue()); //Displays 10

    //At this point getValue and setValue functions are destroyed
    //(in reality they are destroyed at the next iteration of the garbage collector).
    //The local variable 'value' in the foo is no longer referenced by
    //anything and is destroyed too.
}

bar();

其他回答

也许你应该考虑一个以对象为导向的结构而不是内部功能。

    var calculate = {
        number: 0,
        init: function (num) {
            this.number = num;
        },
        add: function (val) {
            this.number += val;
        },
        rem: function (val) {
            this.number -= val;
        }
    };

并从 calculate.number 变量中阅读结果,谁需要“返回”无论如何。

//Addition
First think about scope which defines what variable you have to access to (In Javascript);

//there are two kinds of scope
Global Scope which include variable declared outside function or curly brace

let globalVariable = "foo";

一件事要记住,一旦你宣布了一个全球变量,你可以在你的代码中的任何地方使用它,即使在功能中;

包含仅在您的代码的特定部分可用的变量的本地范围:

函数范围是当您在函数中宣布变量时,您只能在函数内访问变量。

function User(){
    let name = "foo";
    alert(name);
}
alert(name);//error

//Block scope is when you declare a variable within a block then you can  access that variable only within a block 
{
    let user = "foo";
    alert(user);
}
alert(user);
//Uncaught ReferenceError: user is not defined at.....

//A Closure

function User(fname){
    return function(lname){
        return fname + " " lname;
    }
}
let names = User("foo");
alert(names("bar"));

//When you create a function within a function you've created a closure, in our example above since the outer function is returned the inner function got access to outer function's scope

这就是一个初学者围绕一个关闭的头像一个功能被关闭在一个功能的身体也被称为关闭。

关于JavaScript的定义“关闭是一种功能,加上连接到函数创建的范围” -Axel Rauschmayer博士

那么,这会是什么样子呢?这就是一个例子。

function newCounter() {
  var counter = 0;
   return function increment() {
    counter += 1;
   }
}

var counter1 = newCounter();
var counter2 = newCounter();

counter1(); // Number of events: 1
counter1(); // Number of events: 2
counter2(); // Number of events: 1
counter1(); // Number of events: 3

newCounter 通过 increment 关闭, counter 可以通过 increment 引用和访问。

对1和对2将保持自己的价值的跟踪。

简单但希望有一个清晰的观点,什么关闭是围绕所有这些伟大和先进的答案。

好吧,和一个6岁的孩子谈话,我可能会使用随后的协会。

想象一下 - 你正在玩你的小兄弟姐妹在整个房子,你正在移动周围与你的玩具,并将其中的一些带到你的哥哥的房间。 过了一会儿,你的哥哥从学校回来,去了他的房间,他锁在里面,所以现在你不能访问玩具留在那里再直接的方式。

比较一个情况,当一个门被草案锁定,没有人在里面(通用功能执行),然后一些当地的火灾发生并燃烧房间(垃圾收集器:D),然后一个新的房间被建造,现在你可以留下其他玩具在那里(新功能例子),但从来没有得到相同的玩具留在第一间房间例子。

对于一个先进的孩子,我会把这样的东西放在下面,这不是完美的,但它让你感觉到它是什么:

function playingInBrothersRoom (withToys) {
  // We closure toys which we played in the brother's room. When he come back and lock the door
  // your brother is supposed to be into the outer [[scope]] object now. Thanks god you could communicate with him.
  var closureToys = withToys || [],
      returnToy, countIt, toy; // Just another closure helpers, for brother's inner use.

  var brotherGivesToyBack = function (toy) {
    // New request. There is not yet closureToys on brother's hand yet. Give him a time.
    returnToy = null;
    if (toy && closureToys.length > 0) { // If we ask for a specific toy, the brother is going to search for it.

      for ( countIt = closureToys.length; countIt; countIt--) {
        if (closureToys[countIt - 1] == toy) {
          returnToy = 'Take your ' + closureToys.splice(countIt - 1, 1) + ', little boy!';
          break;
        }
      }
      returnToy = returnToy || 'Hey, I could not find any ' + toy + ' here. Look for it in another room.';
    }
    else if (closureToys.length > 0) { // Otherwise, just give back everything he has in the room.
      returnToy = 'Behold! ' + closureToys.join(', ') + '.';
      closureToys = [];
    }
    else {
      returnToy = 'Hey, lil shrimp, I gave you everything!';
    }
    console.log(returnToy);
  }
  return brotherGivesToyBack;
}
// You are playing in the house, including the brother's room.
var toys = ['teddybear', 'car', 'jumpingrope'],
    askBrotherForClosuredToy = playingInBrothersRoom(toys);

// The door is locked, and the brother came from the school. You could not cheat and take it out directly.
console.log(askBrotherForClosuredToy.closureToys); // Undefined

// But you could ask your brother politely, to give it back.
askBrotherForClosuredToy('teddybear'); // Hooray, here it is, teddybear
askBrotherForClosuredToy('ball'); // The brother would not be able to find it.
askBrotherForClosuredToy(); // The brother gives you all the rest
askBrotherForClosuredToy(); // Nothing left in there

正如你可以看到的那样,房间里留下的玩具仍然可以通过兄弟访问,不管房间是否被锁定。

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 中关闭仅仅是访问功能范围。

函数 foo(x) { var tmp = 3;函数栏(y) { console.log(x + y + (++tmp)); // 会记录 16 } 栏(10); } foo(2);

函数栏,以及其与函数 foo 的语法环境的联系,是关闭。

函数 foo(x) { var tmp = 3; 返回函数 (y) { console.log(x + y + (++tmp)); // 还会记录 16 } } var bar = foo(2); bar(10); // 16 bar(10); // 17

一个关闭的最简单的例子是:

var a = 10; 函数测试() { console.log(a); // 将输出 10 console.log(b); // 将输出 6 } var b = 6; 测试();