我在JavaScript中有一个简单的类:
function MyCounter() {
this.counter = 0;
$('#button').click(this.run);
}
MyCounter.prototype.run = function() {
this.counter += 1;
return console.log(this.counter);
};调用该类的方式如下:
var myCounter = new MyCounter();HTML包含一个带有ID=“按钮”的可点击按钮。单击此按钮将在myCounter实例中增加一个内部变量。显然,它失败是因为this.counter不存在,因为在执行绑定处理程序this时,它等于事件,而不是myCounter实例。
解决这一问题的一个简单方法是将“此”保存到其他变量中,并将调用实际处理程序包装为一个匿名函数:
function MyCounter() {
this.counter = 0;
var this2 = this;
$('#button').click(function() {
this2.run();
});
}有没有更好更干净的方法?或者至少,对于如何命名这样的“临时的这个”变量,可能有一个通用的协议/风格指南?
发布于 2016-06-29 17:06:24
您可以只使用.bind()
$('#button').click(this.run.bind(this));.bind()创建了一个小型存根函数,它实际上是为您实现的:
var self = this;
$('#button').click(function() {
return self.run();
});发布于 2016-06-30 02:16:09
在javascript中,这并不是真正的粗糙。这样做的一个常见方法是:
function MyCounter() {
this.counter = 0;
var self = this;
this.run = function() {
self.counter += 1;
console.log(self.counter);
};
$('#button').click(this.run);
}使用es6语法,一个常见的模式是绑定构造函数中的函数:
class MyCounter {
constructor() {
this.counter = 0;
this.run = this.run.bind(this);
$('#button').on('click', this.run);
}
run() {
this.counter += 1;
console.log(this.counter);
}
// And now you can also remove the event listener:
destroy() {
$('#button').off('click', this.run);
}
}但是,这种模式也可以应用于创建js类的旧方法:
function MyCounter() {
this.counter = 0;
this.run = this.run.bind(this);
$('#button').on('click', this.run);
}
MyCounter.prototype.run = function() {
this.counter += 1;
console.log(this.counter);
}
// And again you can also remove the event listener:
MyCounter.prototype.destroy = function() {
$('#button').off('click', this.run);
}这很好,因为在启动类之前,您现在可以从prototype访问run方法。
但我认为这里的底线是,在创建类实例之前,不能将其绑定到类实例。
侧注:在我的所有示例中,run方法在启动时都绑定到类实例。这意味着run方法不需要再次绑定,即$('#button').click(this.run.bind(this));。
还有另一种模式(带有私有变量的单例):
var myCounter = (function() {
var counter = 0
function run() {
counter += 1
console.log(counter)
}
$('#button').on('click', run)
return {
run: run,
destroy: function() {
$('#button').off('click', run)
}
}
})()因为只有一个#button实例,所以没有理由选择多个类实例。
发布于 2016-06-30 02:28:06
我不知道它是什么,但我只是不喜欢bind函数。作为另一种选择,您可以通过将对象实例封装在匿名函数中,从而将this绑定到对象实例,然后使用HTML5的onclick属性将函数绑定到模板。
var MyCounter = (function () {
function MyCounter(counter) {
this.counter = counter || 0;
}
MyCounter.prototype.run = function () {
return alert(this.counter += 1);
};
return MyCounter;
}());
var counterInstance = new MyCounter(10);
window.counterInstance = counterInstance;
...
<button onclick="counterInstance.run()">Test</button>另一种策略--一种更面向对象的方法--将元素引用传递给类本身,并在类构造函数中分配方法。看起来应该是:
class Counter {
constructor(elementRef, counter = 0) {
this.element = elementRef;
this.counter = counter;
//native HTML type
this.element.onclick = () => this.run();
//alternatively
this.element.addEventListener('click', this.run);
}
function run() => { return this.counter++; }
}https://stackoverflow.com/questions/38105978
复制相似问题