未使用 JS 闭包将变量传递给 onClick 函数

Posted

技术标签:

【中文标题】未使用 JS 闭包将变量传递给 onClick 函数【英文标题】:Variable not being passed to onClick function using JS closures 【发布时间】:2015-02-10 22:44:22 【问题描述】:

我读完了Explaining javascript Scope and Closures

但我似乎无法让以下代码工作。如您所见,我尝试了很多变体,但无法将当前值传递给稍后将调用的函数。

当单击 div 时,我希望警报读取“开始”而不是“结束”... 帮忙?

var someString = "START";
document.getElementById('elem1').onclick = function()
   return function(someString)
           alert(someString);
     ();
  ;

document.getElementById('elem2').onclick = function()
           alert(someString);
  ;

document.getElementById('elem3').onclick = function()
    alert(new String(someString));
;

document.getElementById('elem4').onclick = function(someString)
   return function(someString)
           alert(someString);
     ();
  ;

document.getElementById('elem5').onclick = function(someString)
   return function()
           alert(someString);
     ();
  ;


document.getElementById('elem6').onclick = function()
    var newSomeString =someString; 
    alert(newSomeString);
;


var someString = "END";
<body>
<div style="background-color='yellow';display:block;" id="elem1">1</div>
<br>
<div style="background-color='red';display:block;" id="elem2">2</div>
<br>
<div style="background-color='blue';display:block;" id="elem3">3</div>
<br>
<div style="background-color='green';display:block;" id="elem4">4</div>
<br>
<div style="background-color='orange';display:block;" id="elem5">5</div>
<br>
<div style="background-color='pink';display:block;" id="elem6">6</div>
<br>
</body>

【问题讨论】:

【参考方案1】:

问题在于代码何时执行。当您执行单击时,您已经更改了它的值。下面的代码将起作用。

var someString = "START";
function createCallback() 

    var newSomeString = new String(someString);
    return function() 
       alert(newSomeString);
    


document.getElementById('elem').onclick = createCallback();

someString = "END";
<body>
<div style="background-color='pink';display:block;" id="elem">6</div>
<br>
</body>

【讨论】:

谢谢!.. 这行得通,但 createCallBack() 函数不是必需的。我猜的关键是在新函数的范围内创建一个新变量,其值是从内部函数中设置的。但是,为什么这不只是将句柄传递给我不知道的初始 someString 。在 java 中,我会使用 new String 来使其全新......以下对我有用document.getElementById('elem7').onclick = function() var newSomeString = someString; return function() alert(newSomeString ); (); @RomanRekhler,是的,createCallBack 函数只是我个人的偏好。你在这两个方面都是对的。如果我没记错的话,字符串是 JS 中的原始对象。与 Java 一样,原语不被引用。 @RomanaRekhler 不确定您是否注意到我的答案(实际上是在这个答案之前),但我解释了该问题的答案并举了一个例子。当我在那里时,我还修复了你的背景颜色 css。不知道为什么我有时会费心回答。 :)【参考方案2】:

JavaScript 是功能范围的。您正在将回调函数附加到所有这些侦听器,但在实际触发回调之前它们不会执行。到那时,您已经更改了消息的值。

如果你想封装范围,你有几个选择。您可以将附加侦听器的逻辑封装在 IIFE 中。

您也可以将工作转移到准备就绪时运行的函数。这是一个例子:

var someString = "START";

setListener();

function setListener(message) 
    message = message || someString;
    document.getElementById('elem1').onclick = function()
        alert(message);
    ;


var someString = "END";

http://jsfiddle.net/dh2hr2px/1/

【讨论】:

以上是关于未使用 JS 闭包将变量传递给 onClick 函数的主要内容,如果未能解决你的问题,请参考以下文章

PHP:如何将实例变量传递给闭包?

如何将变量传递给动态创建的 javascript onclick 函数? [关闭]

for循环输出i为同一值的问题

使用JS 按钮onclick传递url参数

JS onclick 中如何传两个参数给 JS方法

如何将arraylist传递给onClick的方法