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

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


当前回答

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

关于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将保持自己的价值的跟踪。

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

其他回答

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

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

console.log(x + 3);

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

我倾向于通过好/坏的比较更好地学习,我喜欢看到工作代码跟随不工作的代码,有人可能会遇到,我把一个 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()函数中移动,函数现在只会返回完成的路径,这在第一眼看起来更直观。

结果

TLDR

细节

当一个函数通过内部(呼叫)方法引用时,函数对象的环境参考将复制到新创建的执行框架(stack frame)环境记录的外部环境参考。

在下面的例子中,函数f 关闭了全球执行背景的语法环境:

function f() {}

在下面的例子中,函数h在函数g的语法环境中关闭,而函数h则在全球执行背景的语法环境中关闭。

function g() {
    function h() {}
}

如果内部函数由外部函数返回,则外部语法环境在外部函数返回后将继续存在,因为如果内部函数最终被召回,则外部语法环境必须可用。

答案:这个答案是写的,当问题是:

正如老阿尔伯特所说:“如果你不能向一个六岁的人解释,你真的不明白自己。 好吧,我试图向一个27岁的朋友解释JS的关闭,并且完全失败了。


一时一刻:

有一位公主......

function princess() {

她在一个充满冒险的奇妙世界中生活,她遇到了她的魅力王子,围绕着一个独角兽的世界,战斗的龙,遇到了谈话的动物,以及许多其他幻想的东西。

    var adventures = [];

    function princeCharming() { /* ... */ }

    var unicorn = { /* ... */ },
        dragons = [ /* ... */ ],
        squirrel = "Hello!";

    /* ... */

    return {

她经常会告诉他们她作为公主的最新惊人的冒险。

        story: function() {
            return adventures[adventures.length - 1];
        }
    };
}

但是,他们只会看到一个小女孩。

var littleGirl = princess();

关于魔法和幻想的故事。

littleGirl.story();

即使成年人知道真正的公主,他们永远不会相信单身或龙,因为他们永远不会看到它们。

这是一个真正的公主,里面有一个小女孩。

考虑到以下功能

function person(name, age){

    var name = name;
    var age = age;

    function introduce(){
        alert("My name is "+name+", and I'm "+age);
    }

    return introduce;
}

var a = person("Jack",12);
var b = person("Matt",14);

每次函数人被称为一个新的关闭创建,而变量 a 和 b 具有相同的输入函数,它与不同的关闭有关,而这个关闭仍然存在,即使函数人完成执行后。

此分類上一篇

a(); //My name is Jack, and I'm 12
b(); //My name is Matt, and I'm 14

一个抽象的封闭可以代表到这样的东西:

closure a = {
    name: "Jack",
    age: 12,
    call: function introduce(){
        alert("My name is "+name+", and I'm "+age);
    }
}

closure b = {
    name: "Matt",
    age: 14,
    call: function introduce(){
        alert("My name is "+name+", and I'm "+age);
    }
}

假设你知道一个班级在另一个语言是如何工作的,我会做一个类似。

想想像

JavaScript 作为构建器的本地变量作为例子属性这些属性是私人内部功能作为例子方法

每一天都有一个功能被称为

将创建一个包含所有本地变量的新对象,该对象的方法将访问该对象的“属性”。