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

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


当前回答

函数和函数的外部范围(语法环境)的参考

函数 汽车(制造商,模型,年,颜色) { 返回 { 到String() { 返回 `${ 制造商} ${ 模型} (${ 年}, ${ 颜色})` } } 组车 = 新车(‘Aston Martin’,‘V8 Vantage’,‘2012’,‘Quantum Silver’) console.log(car.toString())

事件导向的编程

在下面的例子中,所有实施细节都隐藏在即时执行的函数表达式内。 函数标记和 toString 接近私人状态和函数他们需要完成工作。 关闭已使我们能够模块化和包容我们的代码。

例子1

这个例子表明,本地变量在关闭中没有复制:关闭保持了对原始变量的参考。

左边

其他回答

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 showPostCard(Sender, Receiver) {

    var PostCardMessage = " Happy Spring!!! Love, ";

    function PreparePostCard() {
        return "Dear " + Receiver + PostCardMessage + Sender;
    }

    return PreparePostCard();
}
showPostCard("Granny", "Olivia");

雖然在網路上有許多美麗的JavaScript關閉定義,但我試圖開始用我最喜歡的關閉定義來解釋我的六歲朋友,這幫助我更好地理解關閉。

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

关闭是指独立(自由)变量的函数,换句话说,关闭中定义的函数“记得”它所创造的环境。

关闭的用途:

关闭是有用的隐藏功能的实施,同时仍然揭示界面。

您可以使用关闭在 JavaScript 中模拟嵌入式概念。

關閉的例子:

function makeAdder(x) {
    return function(y) {
        return x + y;
    };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

function makeAdder(x) {
    return {
        add: function(y){
            return x + y;
        }
    }
}

var add5 = makeAdder(5);
console.log(add5.add(2));//7

var add10 = makeAdder(10);
console.log(add10.add(2));//12

例子3:在jQuery中关闭

$(function(){
    var name="Closure is easy";
    $('div').click(function(){
        $('p').text(name);
    });
});

有用的链接:

感谢上面的链接,这有助于我更好地理解和解释关闭。

第一点的例子 由 dlaliberte:

关闭不只是在您返回内部函数时创建。 事实上,关闭函数根本不需要返回. 您可以将内部函数归咎于外部范围中的变量,或者将其作为一个论点转移到另一个函数,在那里它可以立即使用。

var i;
function foo(x) {
    var tmp = 3;
    i = function (y) {
        console.log(x + y + (++tmp));
    }
}
foo(2);
i(3);

var foo = function() {
  alert("Hello World!");
};

var bar = function(arg) {
  return arg;
};

bar(foo)();

function add(value1, value2) {
  function doAdd(operand1, operand2) {
    return operand1 + operand2;
  }

  return doAdd(value1, value2);
}

var foo = add(1, 2);
// foo equals 3

function add(value1, value2) {
  function doAdd() {
    return value1 + value2;
  }

  return doAdd();
}

var foo = add(1, 2);
// foo equals 3

创建关闭 一个关闭是当一个内部函数从创建它的函数的外部可访问时创建的,这通常发生在一个外部函数返回一个内部函数时,当这种情况发生时,内部函数保持了一个参考到它创建的环境。

function add(value1) {
  return function doAdd(value2) {
    return value1 + value2;
  };
}

var increment = add(1);
var foo = increment(2);
// foo equals 3

function increment(value2) {
  return 1 + value2;
}

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Closures</title>
  <meta charset="UTF-8" />
  <script>
    window.addEventListener("load", function() {
      window.setInterval(showMessage, 1000, "some message<br />");
    });

    function showMessage(message) {
      document.getElementById("message").innerHTML += message;
    }
  </script>
</head>
<body>
  <span id="message"></span>
</body>
</html>

window.addEventListener("load", function() {
  var showMessage = getClosure("some message<br />");

  window.setInterval(showMessage, 1000);
});

function getClosure(message) {
  function showMessage() {
    document.getElementById("message").innerHTML += message;
  }

  return showMessage;
}

模拟私人数据

function Person(name) {
  this._name = name;

  this.getName = function() {
    return this._name;
  };
}

var person = new Person("Colin");

person._name = "Tom";
// person.getName() now returns "Tom"

function Person(name) {
  var _name = name;

  this.getName = function() {
    return _name;
  };
}

var person = new Person("Colin");

person._name = "Tom";
// person._name is "Tom" but person.getName() returns "Colin"

在LOPS

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Closures</title>
  <meta charset="UTF-8" />
  <script>
    window.addEventListener("load", function() {
      for (var i = 1; i < 4; i++) {
        var button = document.getElementById("button" + i);

        button.addEventListener("click", function() {
          alert("Clicked button " + i);
        });
      }
    });
  </script>
</head>
<body>
  <input type="button" id="button1" value="One" />
  <input type="button" id="button2" value="Two" />
  <input type="button" id="button3" value="Three" />
</body>
</html>

要解决这个问题,关闭必须从实际路径变量中分开,这可以通过呼叫一个新的函数来完成,这反过来创造了一个新的参考环境,下面的例子表明如何做到这一点,路径变量转移到 getHandler() 函数, getHandler() 然后返回一个独立于原来的“为”路径的关闭。

function getHandler(i) {
  return function handler() {
    alert("Clicked button " + i);
  };
}
window.addEventListener("load", function() {
  for (var i = 1; i < 4; i++) {
    var button = document.getElementById("button" + i);
    button.addEventListener("click", getHandler(i));
  }
});

function Person(name) {
  var _name = name;

  this.getName = function() {
    return _name;
  };

  this.sayHello = function() {
    alert("Hello!");
  };
}

function Person(name) {
  var _name = name;

  this.getName = function() {
    return _name;
  };
}

Person.prototype.sayHello = function() {
  alert("Hello!");
};

要记住的事情