Skip to content

Instantly share code, notes, and snippets.

@hkusu
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save hkusu/5a2cf09c35f6055db3f3 to your computer and use it in GitHub Desktop.

Select an option

Save hkusu/5a2cf09c35f6055db3f3 to your computer and use it in GitHub Desktop.
(function() {
'use strict';
var SimpleEventEmitter = (function() {
var SimpleEventEmitter = function() {
};
function isString(arg) {
return typeof arg === 'string';
}
function isFunction(arg) {
return typeof arg === 'function';
}
function isUndefined(arg) {
return typeof arg === 'undefined';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
var p = SimpleEventEmitter.prototype;
p.on = function(event, callback) {
if (!isString(event) || !isFunction(callback)) {
throw new TypeError('Invalid argument');
}
if (isUndefined(this.subscribers)) {
this.subscribers = {};
}
if (isUndefined(this.subscribers[event])) {
this.subscribers[event] = [];
}
this.subscribers[event].push(callback);
return callback;
};
p.off = function(event, callback) {
if (isUndefined(callback)) {
if (!isString(event)) {
throw new TypeError('Invalid argument');
}
if (isUndefined(this.subscribers) || isUndefined(this.subscribers[event])) {
return;
}
delete this.subscribers[event];
} else {
if (!isString(event) || !isFunction(callback)) {
throw new TypeError('Invalid argument');
}
if (isUndefined(this.subscribers) || isUndefined(this.subscribers[event])) {
return;
}
var subscribers = this.subscribers[event],
i,
max = subscribers.length;
for (i = 0; i < max; i++) {
var subscriber = subscribers[i];
if (subscriber === callback) {
subscribers.splice(i, 1);
i--;
max--;
}
}
}
};
p.emit = function(event, arg) {
if (!isString(event)) {
throw new TypeError('Invalid argument');
}
if (isUndefined(this.subscribers) || isUndefined(this.subscribers[event])) {
return;
}
var subscribers = this.subscribers[event],
i,
max = subscribers.length;
for (i = 0; i < max; i++) {
var subscriber = subscribers[i];
subscriber(arg);
}
};
p.clear = function() {
if (!isUndefined(arguments[0])) {
throw new TypeError('Invalid argument');
}
this.subscribers = {};
};
SimpleEventEmitter.apply = function(obj) {
if (!isObject(obj)) {
throw new TypeError('Invalid argument')
}
Object.keys(p).forEach(function (key) {
if (p.hasOwnProperty(key) && isFunction(p[key])) {
obj[key] = p[key];
}
});
};
return SimpleEventEmitter;
})();
// 利用例 1) EventEmitter インスタンスを利用
var emitter = new SimpleEventEmitter();
// 利用例 2) 既存のインスタンスに EventEmitter 機能を適用
function Bar(name, age) {
this.name = name;
this.age = age;
SimpleEventEmitter.apply(this);
}
var bar = new Bar('Yamada', 45);
//SimpleEventEmitter.apply(bar); // 後付する場合はこう
// ユースケース(モデル層
var obj = {
name: 'Yamada',
age: 65,
setName: function(name) {
this.name = name;
this.emit('change', 'name を ' + name + ' へ変更しました')
}
};
SimpleEventEmitter.apply(obj);
obj.on('change', function(message) {
console.log(message);
});
obj.setName('Suzuki'); // => name を Suzuki へ変更しました、が出力される
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment