Reputation: 5931
Recently I came across a simple Command pattern implementation in JavaScript that uses function as an object instead of pure object to define functionality:
var CommandManager = (function() {
function CommandManager() {}
CommandManager.executed = [];
CommandManager.unexecuted = [];
CommandManager.execute = function execute(cmd) {
cmd.execute();
CommandManager.executed.push(cmd);
};
CommandManager.undo = function undo() {
var cmd1 = CommandManager.executed.pop();
if (cmd1 !== undefined){
if (cmd1.unexecute !== undefined){
cmd1.unexecute();
}
CommandManager.unexecuted.push(cmd1);
}
};
CommandManager.redo = function redo() {
var cmd2 = CommandManager.unexecuted.pop();
if (cmd2 === undefined){
cmd2 = CommandManager.executed.pop();
CommandManager.executed.push(cmd2);
CommandManager.executed.push(cmd2);
}
if (cmd2 !== undefined){
cmd2.execute();
CommandManager.executed.push(cmd2);
}
};
return CommandManager;
})();
and the usage:
CommandManager.execute({
execute: function(){
// do something
},
unexecute: function(){
// undo something
}
});
//call unexecute of prev. command
CommandManager.undo();
//call execute of prev. command
CommandManager.redo();
My question would be, is there any advantages in defining CommandManager function this way, instead of directly defining properties on object literal and assigning it back to var CommandManager
Upvotes: 0
Views: 70
Reputation: 700302
The only use for that would be that you have a function that does absolutely nothing:
CommandManager(); // does nothing, returns undefined
Other than that, you can just as well write the code as an object literal and use this
to avoid it being dependant on its own name:
var CommandManager = {
executed: [],
unexecuted: [],
execute: function execute(cmd) {
cmd.execute();
this.executed.push(cmd);
},
undo: function undo() {
var cmd1 = this.executed.pop();
if (cmd1 !== undefined){
if (cmd1.unexecute !== undefined){
cmd1.unexecute();
}
this.unexecuted.push(cmd1);
}
},
redo: function redo() {
var cmd2 = this.unexecuted.pop();
if (cmd2 === undefined){
cmd2 = this.executed.pop();
this.executed.push(cmd2);
this.executed.push(cmd2);
}
if (cmd2 !== undefined){
cmd2.execute();
this.executed.push(cmd2);
}
}
}
Upvotes: 1