【问题标题】:Variable not being passed to onClick function using JS closures未使用 JS 闭包将变量传递给 onClick 函数
【发布时间】: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>

【问题讨论】:

    标签: javascript onclick scope closures


    【解决方案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/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-19
      • 1970-01-01
      • 2019-04-21
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 2012-08-20
      相关资源
      最近更新 更多