JavaScript:回调函数与匿名函数 - 为什么只有其中一个触发?

时间:2016-02-11 10:45:26

标签: javascript

我注意到有关事件回调函数的一些奇怪内容,我不确定发生了什么。

给出以下示例:

HTML

<button id=btn1>Click #1</button>

<button id=btn2>Click #2</button>

的JavaScript

$(function() {
  var $button1 = $('#btn1');
  var $button2 = $('#btn2');

  $button1.on('click', function() {
    validate();
  });

  $button2.on('click', validate);

  var validate = _.debounce(function() {
    alert('validate fired');
  });
});

Fiddle

为什么Button#1成功触发validate功能,而Button#2不成功?

我的猜测是因为匿名函数是动态评估而另一个不是,因此validate尚未定义,但我不确定。有人可以赐教我吗?

4 个答案:

答案 0 :(得分:2)

这两个功能都是匿名的。

这两个函数都是回调函数。

第二个不会触发,因为您先将public void login() { try { if (USERNAME != "" && PASS != "") { byte[] utf8Bytes = Encoding.UTF8.GetBytes(PASS); String unicodePass = Encoding.Unicode.GetString(utf8Bytes); string login = "SELECT * from rfidprototype.account where username ='" + USERNAME + "' and UNICODE(password) = '" + unicodePass + "';"; MySqlCommand cmdDB = new MySqlCommand(login, SQLconn); MySqlDataReader DRead; DRead = cmdDB.ExecuteReader(); if (DRead.Read()) { if (USERNAME == "admin") { MenuHere menu = new MenuHere(); menu.Show(); SQLconn.Close(); } else { MenuHere menu1 = new MenuHere(); menu1.Show(); menu1.ManageTile.Enabled = false; SQLconn.Close(); } } else { //MessageBox.Show("Incorrect Username or Password!"); MessageBox.Show("Incorrect Username or Password", "Laptop Ownership Identifier System", MessageBoxButtons.OK, MessageBoxIcon.Error); DiriLogin form = new DiriLogin(); form.ShowDialog(); } } else { // MessageBox.Show("Incorrect Username or Password!"); MessageBox.Show("Please input username or password", "Laptop Ownership Identifier System", MessageBoxButtons.OK, MessageBoxIcon.Error); DiriLogin form = new DiriLogin(); form.ShowDialog(); } }catch(Exception ex) { MessageBox.Show(ex.Message); } } 的值传递给validate ,然后首先将值分配给on()(即它仍然是validate)。

如果您使用了函数声明:

undefined

...然后它会被悬挂所以顺序无关紧要。

由于您使用的是表达式(即对function validate() { // ... } 的调用的返回值),因此订单确实很重要。

答案 1 :(得分:0)

变量提升后实际运行的代码就是这个。

$(function() {
  var validate; // NOTICE the validate variable is hoisted.
  var $button1 = $('#btn1');
  var $button2 = $('#btn2');

  $button1.on('click', function() {
    validate();
  });

  $button2.on('click', validate); // here, validate is undefined.

  validate = _.debounce(function() {
    alert('validate fired');
  });
});

因此,当您将验证放入.on处理程序时,它尚未定义。

答案 2 :(得分:0)

简单地说,由于$button2.on('click', undefined);hoisted,第二次调用等同于写var variable。第一个回调是在为其分配警报功能时引用var validate

答案 3 :(得分:0)

你必须小心宣布你的功能。函数声明,函数表达式以及它们如何处理提升之间存在差异。

使用功能声明,该功能始终挂起

   //function declaration
    function validate() {
      //do stuff
    }

使用函数表达式,只有变量声明才会被提升。变量分配未被提升

//function expression
//unamed (anonymous function)
var validate = function() {
  //do stuff
}

因此,在您的情况下, validate 未定义为按钮#2

这是一篇深入探讨问题的文章: https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/