为什么这不是一个javascript闭包

Why is this not a javascript closure?

本文关键字:一个 javascript 闭包 这不是 为什么      更新时间:2023-09-26

>我有 2 个按钮:按钮 1 和按钮 2。 我有以下代码:

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

当我单击按钮1时,我得到"hello 2"。 我以为这将是结束,我会得到"你好 1"。 请帮忙

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

JavaScript

中的 Scope 是函数中的 hold。每次声明函数时,它都会创建一个作用域(闭包)。所以,是的,你创建了一个闭包,但你看到的行为是你应该期待的。

在这里,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

然后,每个作用域都引用其父作用域,以搜索不属于其自身作用域的变量。

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

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

如果你的速度快得不可思议,你的浏览器运行相对较慢,你可能会设法点击你的#button1并得到hello 1如果JS引擎实际上还没有设法真正开始执行那message = 'hello 2';行。但这基本上是不可能的。你没那么快。

虽然这些是闭包,但两个闭包都引用了message变量。当调用 #button1 on click 函数时(当用户单击它时),它使用 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);
  });
});