向JavaScript对象添加侦听器函数
Adding listener functions to a JavaScript object
我有以下定义Car
的代码。每个Car
都有一种颜色,还有一个setColor(color)
函数。我想添加每当调用setColor(color)
时都会调用的侦听器函数,并且我希望能够在需要的时候添加这些侦听器函数。这是一个合适的方法吗?有更干净的方法吗?
function Car() {
this._color = 'red';
this._callbacks = {};
this.setColor = function(color) {
this._color = color;
console.log(">>> set car color to " + color);
if (this._callbacks['setColor']) {
this._callbacks['setColor']();
}
};
this.addListener = function(functionName, handler) {
if (this._callbacks[functionName]) {
var oldCallback = this._callbacks[functionName];
this._callbacks[functionName] = function() {
oldCallback();
handler();
}
} else {
this._callbacks[functionName] = function() {
handler();
}
}
};
}
var car = new Car();
car.setColor('blue');
car.addListener('setColor', function() { console.log("This is listener # 1"); });
car.setColor('green');
car.addListener('setColor', function() { console.log("This is listener # 2"); });
car.setColor('orange');
输出:
>>> setColor to blue
>>> setColor to green
This is listener # 1
>>> setColor to orange
This is listener # 1
This is listener # 2
我认为存储侦听器的数组将是一种更干净的方法。此外,您应该使用原型对象,或者使半私有属性成为真正的私有变量。
function Car() {
this._color = 'red';
this._callbacks = {setColor:[]};
};
Car.prototype.setColor = function(color) {
this._color = color;
console.log(">>> set car color to " + color);
for (var i=0; i<this._callbacks['setColor'].length; i++)
this._callbacks['setColor'][i]();
};
Car.prototype.addListener = function(functionName, handler) {
this._callbacks[functionName].push(handler);
};
或者:
function Car() {
var color = 'red';
var callbacks = {};
this.setColor = function(c) {
color = c;
console.log(">>> set car color to " + color);
for (var i=0; 'setColor' in callbacks && i<callbacks['setColor'].length; i++)
callbacks['setColor'][i]();
};
this.addListener = function(functionName, handler) {
if (functionName in callbacks)
callbacks[functionName].push(handler);
else
callbacks[functionName] = [handler];
};
}
也许是这样的。
//the 'class'
function Car() {
//set up a static listeners object - an array for each method
Car.listeners = {setColor: []};
//called by methods on invocation, to fire their listeners
Car.executeListeners = function(methodName) {
for (var i=0, len = Car.listeners[methodName].length; i<len; i++)
Car.listeners[methodName][i].apply(this);
};
//method - on invocation, fire any listeners
this.setColor = function(color) {
this.color = color;
Car.executeListeners.call(this, 'setColor');
};
}
//instance
var car = new Car();
//add a listener to instance.setColor invocations
Car.listeners.setColor.push(function() {
alert("hello - this car's color is "+this.color);
});
//set color (triggers listener)
car.setColor('orange');
请注意,您将原型esq方法分配给实例,而不是分配给原型本身——这是继承的、可重用功能的地方。继承在性能方面也更快。
如果它对你有效,那么我认为没有理由不采用它。关于这种方法的一些想法:
- 不能设置处理程序的上下文,如果应该针对某个对象调用处理程序,则应该让
addListener
方法获取上下文对象并执行callback.call(context)
。如果你不在乎这个,那么就不用担心了 - 如果早期回调失败,则不会调用后期回调。不确定你是否关心这一点,但如果你关心,你可以使用一个数组来存储所有回调,并在数组上迭代,依次调用每个回调。您可能需要将对回调的调用封装在try/catch块中,以确保不断调用回调
- 是否要将当前颜色传递给回调?甚至是Car对象本身,类似于
callback(this, this._color)
- 您的方法使用了相当数量的闭包。如果您发现性能成为一个问题,那么去掉闭包会有所帮助
另一件需要考虑的事情是使用Object.defineProperty
,但这是一个更具风格的选择。
相关文章:
- 加载侦听器上的函数触发得太早
- 在NodeJS中使用类函数作为事件侦听器
- 向JavaScript对象添加侦听器函数
- 函数内的事件侦听器
- 如何从函数引用元素(从事件侦听器调用)
- 为什么在定义回调/侦听器函数(异步消息传递,port.on)后没有立即设置全局变量
- ReactJS:在 JQuery 事件侦听器函数中调用 'this'
- 在侦听器函数 (Javascript) 中调用方法时引用错误
- 将参数传递给 javascript 中的事件侦听器函数
- 仅在侦听器函数中加载脚本/模块会导致问题吗?
- 如何将参数传递给在 addEventListener 中传递的侦听器函数
- 在返回 false 后停止添加的事件侦听器函数
- 如何创建一个javascript侦听器函数,该函数将在条件为true时执行操作
- 删除类不会;t禁用与已删除类关联的事件侦听器函数
- 在没有jquery的情况下只执行一次事件侦听器函数
- 如何在JavaScript中将局部变量从函数传递到事件侦听器函数
- 动态添加事件侦听器.函数触发,但我如何发送一个变量参数
- 如何将变量传递给事件侦听器函数
- .trigger()中的额外参数无法到达侦听器函数:正在发生什么
- 绑定事件侦听器函数,以后需要调用函数吗?