我是前端编程的新手。当我学习Jquery时,我遇到了这个问题。 这是我的下面代码
<script type="text/javascript">
$(document).ready(function(){
var msg ="hi";
$("#test1").click(function(){alert(msg)});
msg ="hello";
$("#test2").click(function(){alert(msg)});
});
</script>
</head>
<body>
<button id="test1">test1</button>
<button id="test2">test2</button>
在运行此代码时,两个警报都会打印“hello”。我点击的第一个按钮除了“hi”警告。有人能解释我为什么会这样吗?这是礼仪行为吗?是因为范围限制吗?请帮帮我。
答案 0 :(得分:5)
您有范围问题。
当您到达实际点击 msg === "hello"
答案 1 :(得分:2)
执行处理程序代码时,msg
的值为“hello”。
或者你可以将它作为数据传递给处理函数访问它..
$(document).ready(function(){
var msg ="hi";
$("#test1").click({msg: msg}, function(e){alert(e.data.msg)});
msg ="hello";
$("#test2").click({msg: msg}, function(e){alert(e.data.msg)});
});
答案 2 :(得分:1)
在准备好文档时,您的javascript代码已执行。此时,单击函数绑定到两个按钮,msg
首先设置为hi,然后执行下一行,msg
被hello覆盖。
触发点击时msg
已经被覆盖,因此输出你好。
这是正确的和预期的行为。您可以通过使用两个变量或在单击时(在单击功能中)设置它们来克服此问题。
答案 3 :(得分:1)
这里有很多大致正确的解释,但令我惊讶的是,没有人抛出关键概念:封闭。
基本上发生的事情是当你声明你的两个函数时,它们声明的范围形成一个闭包。这意味着该闭包内的变量仍然可用于函数。换句话说:
$(document).ready(function(){
// this begins a closure
var msg ="hi";
// you are simply declaring a function here, not calling it
$("#test1").click(function(){alert(msg)});
msg ="hello";
// ditto
$("#test2").click(function(){alert(msg)});
// the end of the closure...msg has the value "hello"
});
然后一段时间过去了,点击事件就会被调用。附加到click事件的函数仍然可以访问闭包(其中msg
的值是“hello”)。
在闭包内“捕获”变量值的传统方法是创建"Immediately Invoked Function Expression" (IIFE)。基本上你可以把它想象成创建一个包含变量的直接值的全新闭包。您可以重新编写代码以使用这样的IIFE:
$(document).ready(function(){
// this begins a closure
var msg ="hi";
// the following creates an anonymous function with a single parameter
// AND invokes it immediately, creating another closure in which the
// value of msg1 is "hi".
(function(msg1){
$("#test1").click(function(){alert(msg1)});
})(msg);
msg ="hello";
// ditto
(function(msg2){
$("#test2").click(function(){alert(msg2)});
})(msg);
});
我希望这会使发生的事情变得更加清晰,以及如何获得你想要的东西。
答案 4 :(得分:0)
这是预期的行为。它通常不直观,但是javascript是如何工作的。获得预期结果的最简单方法是使用如下函数:
$(document).ready(function(){
var msg ="hi";
$("#test1").click(getCallback(msg));
msg ="hello";
$("#test2").click(getCallback(msg));
});
function getCallback(msg){
return function(){
alert(msg);
}
}
msg
中的getCallback
参数为每个调用都有一个单独的msg
变量,它将为每个单独的调用保持正确的值。