有关jQuery.on()方法中“ this”的问题

时间:2019-05-21 03:59:58

标签: javascript jquery scope this event-binding

事件绑定是JS中的一种常见模式,这是从我读到的代码中进行编码的一种方法:$('#toggle-all').on('change', this.toggleAll.bind(this));

在这种情况下,有一个ID为 toggle-all 的输入,单击该输入即可运行this.toggleAll方法。

但是,即使没有绑定,例如$('#toggle-all').on('change', this.toggleAll);toggleAll方法仍然可以运行,尽管它在方法途中遇到了错误。但是它仍然运行。

但是,对于另一种方法:todoLi.appendChild(this.createDeleteButton());

this.createDeleteButton() 如果我不绑定它根本不会运行。这两个例子有什么区别?我知道一个传递(回调)函数作为参数,而另一个则直接运行该方法。但是第二个示例没有绑定根本不会运行,而this.toggleAll方法即使没有绑定也可以运行。为什么会这样?

var App = {
    bindEvents: function () {
        $('#toggle-all').on('change', this.toggleAll); // without binding
    }, 

    toggleAll: function (e) {
        console.log(this); // prints jQuery object which is the input #toggle-all
        var isChecked = $(e.target).prop('checked');

        // error from this line onward, which is expected.
        this.todos.forEach(function (todo) { // "this" is the input element, hence error
           todo.completed = isChecked;
        });

       this.render();
    }
};

对于第二个选项,代码如下:

var view = {
  displayTodos: function() {
    var todosUl = document.querySelector('ul');
    todosUl.innerHTML = '';

    todoList.todos.forEach(function(todo, position) {
      var todoLi = document.createElement('li');
      var todoTextWithCompletion = '';

      if (todo.completed === true) {
        todoTextWithCompletion = '(x) ' + todo.todoText;
      } else {
        todoTextWithCompletion = '( ) ' + todo.todoText;
      }

      todoLi.id = position;
      todoLi.textContent = todoTextWithCompletion;
      todoLi.appendChild(this.createDeleteButton());
      todosUl.appendChild(todoLi);
    }, this); // binding "this". If I remove it, the error I get in the console is: client.js:90 Uncaught TypeError: this.createDeleteButton is not a function
  },

  // creates a delete button beside every li element in the DOM.
  createDeleteButton: function() {
    console.log(this);
    var deleteButton = document.createElement('button');
    deleteButton.textContent = 'Delete';
    deleteButton.className = 'deleteButton';
    return deleteButton;
  },

主要问题:为什么没有绑定就可以运行方法(在第一种情况下)。但是在第二种情况下,没有绑定就无法运行它吗? 又名 为什么jQuery.on()接受未绑定的this.toggleAll,但是appendChild无法接受未绑定的this.createDeleteButton()?

0 个答案:

没有答案