在对象中使用Javascript这个关键字

时间:2016-05-12 05:20:15

标签: javascript jquery this

我有这个对象:

var eventDisplay = {
  eventTable: $('.table-event > table'),
  archiveButton: $('table-event__archive-button'),
  deleteButton: $('table-event__delete-button'),
  checkedCheckboxes: $('.table-event input[type=checkbox]'),
  countChecked: function() {
    return this.checkboxes.filter(':checked').length;
  },
  selectionChanged: function() {
    if (this.countChecked() > 0) {
      deleteButton.removeClass("disabled");
      archiveButton.removeClass("disabled");
    } else {
      deleteButton.addClass("disabled");
      archiveButton.addClass("disabled");
    }
  },
  attachCheckboxHandler: function() {
    this.checkboxes.on('click', this.selectionChanged);
  }
}

当我致电eventDisplay.attachCheckboxHandler()时,attachCheckboxHandler中的this正在按照我的预期引用该对象。但是,在调用selectionChanged时,this会引用复选框。但我希望selectionChanged中的this引用eventDisplay。有可能吗?如果是这样,怎么样?

3 个答案:

答案 0 :(得分:0)

这是因为事件函数中的this关键字与函数的调用者有关,而不一定是整个实例(如您所发现的那样)。

例如,可能会触发事件,如下所示:

// checkbox has been selected
checkbox.selectionChanged.call();

然后在您的回调中,this将成为复选框实例。

由于您要将主对象分配给变量,您应该只能在回调中引用它:

var eventDisplay = {
  selectionChanged: function() {
    if (eventDisplay.countChecked() > 0) { <-- note here
      deleteButton.removeClass("disabled");
      archiveButton.removeClass("disabled");
    } else {
      deleteButton.addClass("disabled");
      archiveButton.addClass("disabled");
    }
  }
}

答案 1 :(得分:0)

在非常具体的情况下,上下文(this)会发生变化;通常,当您使用点表示法调用方法(设置为对象属性的函数)时。例如,foo.bar()会将this设置为foo

如果您不使用点表示法调用函数,则通常不会更改上下文。例如,baz = foo.bar; baz()看起来与上述内容相同,但不会将this设置为foo(它会保持不变)。

在您的代码中发生了同样的事情,但是您没有使用局部变量赋值,而是传递参数:function quux(baz) { baz(); }; quux(foo.bar)foo.bar分配给baz,就像上面一样。< / p>

您可以做的是将新上下文绑定到函数:baz = foo.bar.bind(foo); baz()每次调用foo时都会将上下文设置为baz。或者,等效地,您可以将baz绑定到将正确调用foo.bar()的包装函数:baz = function() { foo.bar(); }; baz();

这如何转换为您的示例:

this.checkboxes.on('click', this.selectionChanged.bind(this));

(为了完整性,除了方法调用和绑定函数调用之外,还在使用new运算符时设置了上下文,并使用callapply函数设置了< / p>

答案 2 :(得分:0)

通常的做法是将对象声明为函数并为其创建别名(我使用thiz),您可以在方法中使用它。最后,返回实际对象,只显示所需的函数。现在所有的thiz都引用了同一个对象。

var myObj = function() {
    var thiz = this;
    var method1 = function (args) {
        // use thiz here
    }
    // define more methods of you want, such as method2...

    return {
        method : method1,
        anotherMethod : method2
    };
}