javascript - 调用对象中设置的匿名函数,未得到预期结果

标签 javascript jquery twitter-bootstrap

我正在尝试编写一个有点通用的模式对话框处理函数,因此我可以将控件传递给它来处理不同的操作。听起来很简单,我也这么认为。我试图在一个对象中传递按钮处理程序函数,该对象循环通过 ID 将每个函数注册到按钮单击处理程序。它有效,但不是以我期望的方式。这是代码(需要 bootstrap 3):

function confirmation(question){
    var modalTitle = 'Confirmation';
    var modalContents = question;
    var modalControls = '<button type="button" class="btn btn-primary" id="confirmYes">Confirm</button> <button type="button" class="btn btn-default" id="confirmNo">Cancel</button>';

    var modalButtons = {
        confirmNo: function(){
            console.log('really, no!');
        },
        confirmYes: function(){
            console.log('really, yes!');
        }
    }

    standardModal(modalTitle,modalContents,modalControls,modalButtons);
}

function standardModal(modalTitle,modalContents,modalControls,modalButtons){
    $('#standardModalTitle').html(modalTitle);
    $('#standardModalBody').html(modalContents);
    $('#standardModalControls').html(modalControls);

    for (var prop in modalButtons){
        if(!modalButtons.hasOwnProperty(prop)) continue;

        $('#'+prop).click(function(e){
            e.preventDefault();
            modalButtons[prop]();
        });
    }

    $('#standardModal').modal('show');
}

这是 HTML:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<div class='modal fade' tabindex='-1' role='dialog' id='standardModal'>
  <div class='modal-dialog'>
    <div class='modal-content'>
      <div class='modal-header'>
        <button type='button' class='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>&times;</span></button>
        <h4 class='modal-title' id='standardModalTitle'></h4>
      </div>
      <div class='modal-body' id='standardModalBody'>

      </div>
      <div class='modal-footer' id='standardModalControls'>
        <button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
      </div>
    </div>
  </div>
</div>

当我运行确认时('这是一个问题?');对话框中应该有两个按钮:确认和取消。我希望确认运行 modalButtons.confirmYes 函数,而取消应该运行 modalButtons.confirmNo。实际发生的情况是,两个按钮都调用了 modalButtons 中定义的最后一个函数。如果confirmYes 是最后定义的函数,则它会针对两个按钮运行。

当我在那里抛出console.log语句时,变量输出是我每次所期望的......但实际的函数调用是错误的。

我做错了什么?

最佳答案

当您单击按钮并调用 modalButtons[prop]() 时,prop 的计算结果是什么?记住 javascript 如何查找变量名称:

  1. 如果变量是本地定义的,则使用该值
  2. 否则,一次走出 1 个作用域,直到到达全局(窗口)作用域,并查看那里是否定义了具有给定名称的变量
  3. 否则,解析为未定义

在我们的例子中,您单击按钮,然后执行 click 回调,并且 javascript 尝试查找 prop 的值:

  1. prop 未在回调的作用域中定义,因此它会查看下一个外部作用域
  2. prop 在回调的直接父作用域中定义! prop 的值是多少?嗯,这是您循环的最后一个值(数组的最后一个元素)。

您想要做的是定义一个始终指向 prop 预期值的变量。最简单的方法是用函数迭代器替换 for 循环:

Object.keys(modalButtons).forEach(function (prop) {
   // same loop code as before
})

不同之处在于,我们在父作用域中声明一个名为 prop 的新变量,而不是声明一次 prop 并在每次滚动时更改其值循环。这是一个微妙的错误,但您会经常遇到,因此了解其工作原理非常重要。

这有帮助吗?

或者查看我对此的回答 similar question ,如果有帮助请告诉我!

关于javascript - 调用对象中设置的匿名函数,未得到预期结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36751503/

相关文章:

javascript - 如何在 ES6 中调用 bootstrap 的 jQuery 插件

javascript - Kendo Grid 删除事件的自定义警报

javascript - Chrome identity launchWebAuthFlow 只打开空的回调页面

jquery - 图像上的弹出效果

javascript - 提交后重置 HTML 表单

javascript - 从 DOM 中删除 bootstrap Modal

javascript - 填写下拉菜单和单选按钮选项以继续访问正确的网址

javascript - 将 javascript 和 css 存储在数据库中是个坏主意吗?

jQuery AJAX 在不应该生成 304 响应时生成 304 响应

javascript - 在javascript中动态增加HTML表格的行大小