将功能视为对象的优点

时间:2015-10-14 07:42:00

标签: javascript design-patterns

最近我在JavaScript中遇到了一个简单的Command模式实现,它使用函数作为对象而不是纯对象来定义功能:

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;
})(); 

和用法:

CommandManager.execute({
  execute: function(){
    // do something
  },
  unexecute: function(){
    // undo something
  }
});

//call unexecute of prev. command
CommandManager.undo(); 
//call execute of prev. command
CommandManager.redo(); 

我的问题是,以这种方式定义CommandManager函数是否有任何优势,而不是直接定义对象文字的属性并将其分配回var CommandManager

1 个答案:

答案 0 :(得分:1)

唯一用途就是你有一个绝对没有的功能:

CommandManager(); // does nothing, returns undefined

除此之外,您还可以将代码编写为对象文字,并使用this来避免它依赖于自己的名称:

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); 
    }
  }

}