最近我一直在尝试用JavaScript制作一个具有以下结构的对象:
function colorDiv(div){
this.div=div;
this.div.bind("click",this.changeColor)
this.changeColor(){
this.div.css("background", "#FF0000");
}
}
问题是changeColor
方法不能从jQuery环境中调用,因为this
必须引用当前的colorDiv
对象,所以bind方法不能像预期的那样工作。如何解决这个问题?
有几种方法。最简单的如下:
function ColorDiv(div) {
var that = this;
that.div = div;
that.div.bind("click", that.changeColor);
that.changeColor = function () {
that.div.css("background", "#FF0000");
};
}
var colorDiv = new ColorDiv($("#my-div"));
$("#something-else").click(colorDiv.changeColor);
在变量that
中保存对this
的引用,这正是JavaScript世界中用于此目的的常用名称。然后在changeColor
方法中引用that
而不是this
。(请注意,我在所有地方都使用了that
,只是为了保持一致性,即使它真正起作用的唯一地方是在changeColor
方法内部。)
另一种是使用Function#bind
方法。您可以在每次调用changeColor
时使用它,如下所示:
var colorDiv = new ColorDiv($("#my-div"));
$("#something-else").click(colorDiv.changeColor.bind(colorDiv));
或者您可以在ColorDiv
类中使用它来确保无论何时调用所有方法都被正确绑定:
this.changeColor = (function () {
this.div.css("background", "#FF0000");
}).bind(this);
正如链接文章中所指出的,Function#bind
不是在所有浏览器中都支持的,所以你需要一个像他们提供的那样的垫片,或者可能是一个完整的ES5垫片。
Underscore.js有一个bindAll函数,在这里也很有用,特别是在有多个方法的情况下:
_.bindAll(this);
最后,值得注意的是,在您的特定示例中实际上不需要执行任何这些操作:只需执行
this.changeColor = function () {
div.css("background", "#FF0000");
};
而不是你所拥有的,即引用传入的div
变量,而不是存储在this.div
中的引用,因为它们是一样的。
尝试设置为方法的第一行:
var self = this;
,然后在需要时使用self。
this.div.bind("click",self.changeColor)