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

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


当前回答

TLDR

细节

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

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

function f() {}

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

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

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

其他回答

在模块模式中,您定义了一个函数,然后立即在所谓的即时启动函数表达(IIFE)中呼叫它。 您在该函数中所写的一切都有私人范围,因为它在关闭中定义,从而允许您在JavaScript中“模拟”隐私。

 var Closure = (function () {
    // This is a closure
    // Any methods, variables and properties you define here are "private"
    // and can't be accessed from outside the function.

    //This is a private variable
    var foo = "";

    //This is a private method
    var method = function(){

    }
})();

另一方面,如果您希望在关闭室外看到一个或多个变量或方法,您可以将其返回对象内部。

var Closure = (function () {
  // This is a closure
  // Any methods, variables and properties you define here are "private"
  // and can't be accessed from outside the function.

  //This is a private variable
  var foo = "";

  //This is a private method
  var method = function(){

  }

  //The method will be accessible from outside the closure
  return {
    method: method
  }

})();

Closure.method();

希望能帮忙......看,

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

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

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

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

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

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

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);

标签:猴子

在上面的例子中,outerFunction 被称为,其次称为 innerFunction. 请注意,outerVar 是如何向 innerFunction 提供的,通过正确警告 outerVar 的值来证明。

标签:猴子

referenceToInnerFunction 设置为 outerFunction(),它简单地返回一个参考到 innerFunction. 当 referenceToInnerFunction 被召回时,它返回 outerVar. 再次,如上所述,这表明 innerFunction 有访问 outerVar,一个变量 outerFunction. 此外,值得注意的是,它保留这个访问,即使 outerFunction 完成执行后。

警告:猴子警告:猴子警告

關閉的兩件事要注意:第一,關閉總是會有其內容功能的最後價值的存取。

函数外( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( ) 函数( )

我思考关闭的越多,我会看到它作为一个2步过程: init - 行动

init: pass first what's needed...
action: in order to achieve something for later execution.

到6岁时,我会强调关闭的实际方面:

Daddy: Listen. Could you bring mum some milk (2).
Tom: No problem.
Daddy: Take a look at the map that Daddy has just made: mum is there and daddy is here.
Daddy: But get ready first. And bring the map with you (1), it may come in handy
Daddy: Then off you go (3). Ok?
Tom: A piece of cake!

例如:把一些牛奶带到妈妈(=行动)。首先做好准备,然后把地图(=init)带到这里。

function getReady(map) {
    var cleverBoy = 'I examine the ' + map;
    return function(what, who) {
        return 'I bring ' + what + ' to ' + who + 'because + ' cleverBoy; //I can access the map
    }
}
var offYouGo = getReady('daddy-map');
offYouGo('milk', 'mum');

因为如果你带着一个非常重要的信息(地图),你有足够的知识来执行其他类似的操作:

offYouGo('potatoes', 'great mum');

对于一个开发人员来说,我会在关闭和OOP之间进行平行。 init 阶段类似于在传统 OO 语言中向构建者传达论点; 行动阶段最终是你呼吁实现你想要的方法。

请参见我的另一个答案,描述OO和关闭之间的平行性:

如何在JavaScript中“正确”创建自定义对象?

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

    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