I am trying to understand how Facebook Flux works by looking at the source code of their flux chat example.
There, I saw this code:
var MessageStore = assign({}, EventEmitter.prototype, {
emitChange: function() {
this.emit(CHANGE_EVENT);
},
/**
* @param {function} callback
*/
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
...
}
...
module.exports = MessageStore;
...where assign is just polyfilled Object.assign from ES6 spec.
Hm. Would this code, using classes and extends instead, work? Would it mean the same thing? What are differences and advantages/disadvantages of this approach?
class MessageStore extends EventEmitter {
emitChange() {
this.emit(CHANGE_EVENT);
}
addChangeListener(callback) {
this.on(CHANGE_EVENT, callback);
}
...
}
module.exports = new MessageStore();
I am asking, because, coming from other languages, I intuitively understand class/extends, while prototype-based inheritance is always a little unclear to me.
Here is working code that you can use with regards to ES6 syntax and your situation:
import EventEmitter from 'events';
const CHANGE_EVENT = 'change';
class MessageStore extends EventEmitter {
constructor() {
super();
}
addChangeListener = (callback) => {
this.on(CHANGE_EVENT, callback);
}
removeChangeListener = (callback) => {
this.removeListener(CHANGE_EVENT, callback);
}
emitChange = () => {
this.emit(CHANGE_EVENT);
}
}
Note, I prefer the ES6 function literal syntax because it ensures that "this" is always bound to the enclosing object context.
For a fully working ES6 store example, please feel free to review the stores code in my Babel React Starter App
This is also a useful reference on ES6 classes that visually explains what is going on inside the body of a class definition.