我有这个对象:
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
。有可能吗?如果是这样,怎么样?
答案 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
运算符时设置了上下文,并使用call
和apply
函数设置了< / 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
};
}