为什么这不是一个javascript闭包?

时间:2013-10-22 18:16:04

标签: javascript closures

我有2个按钮:button1和Button2。我有以下代码:

$(document).ready(function() {
  var message = "hello 1";
  $("#button1").on("click", function() {
    alert(message);
  });
  message = "hello 2";
  $("#button2").on("click", function() {
    alert(message);
  });
});

当我点击button1时,我得到“你好2”。我以为这会关闭,我会得到“你好1”。请帮忙

4 个答案:

答案 0 :(得分:3)

闭包不保存变量的,它只保存一个特定的局部变量实例。因此赋值message = "hello 2"更新两个闭包中的变量。

答案 1 :(得分:3)

JavaScript中的范围保存在一个函数中。每次声明一个函数时,它都会创建一个范围(一个闭包)。所以,是的,你创建了一个闭包,但你看到的行为是你应该期待的行为。

此处,message的范围限定为文档就绪回调。并且每个点击处理程序在搜索消息变量值时引用相同的范围。因此,message变量在触发点击事件时保持相同的值。

要查看它,只需将范围检查为链:

"document ready"
  - var message (it is declared here and can only have one value at a given time)
  - "#button1 click handler"
    - no var (so it'll search the parent scope for the value)
  - "#button2 click handler"
    - no var

然后,每个范围引用其父范围来搜索不属于其自身范围的变量。

答案 2 :(得分:1)

您正在定义全局变量message,并为其指定值。当执行。on('click'...内容时,message变量的名称嵌入在那些新创建的函数中,而不是它在函数定义时的值。

因此,当您实际点击这些按钮时,JS会获取嵌入在函数中的变量NAME,查找其CURRENT值(即'hello 2'),并且输出就是。

如果您的速度非常快且浏览器运行速度相对较慢,您可能会设法点击#button1并获取hello 1 IF JS引擎没有实际上设法实际开始执行message = 'hello 2';行。但这基本上是不可能的。你不是那么快。

答案 3 :(得分:0)

虽然这些是闭包,但两个闭包都引用了message变量。当调用#button1点击功能时(当用户点击它时),它会使用message变量的当前值,该变量在准备好之前更改为"hello 2"功能

您可以通过不为不同的消息重复使用相同的变量来避免这种情况,如下例所示:

$(document).ready(function() {
  var message1 = "hello 1";
  $("#button1").on("click", function() {
    alert(message1);
  });
  var message2 = "hello 2";
  $("#button2").on("click", function() {
    alert(message2);
  });
});