zxhfighter
12/18/2013 - 3:42 AM

javascript design patterns

javascript design patterns

JavaScript设计模式

阅读本书需要一些JavaScript基础,推荐阅读这些书籍:

  • 《JavaScript: The Definitive Guide》 by David Flanagan
  • 《Eloquent JavaScript》 by Marijn Haverbeke
  • 《JavaScript Patterns》 by Stoyan Stefanov
  • 《Writing Maintainable JavaScript》 by Nicholas Zakas
  • 《JavaScript: The Good Parts》 by Douglas Crockford

模式和反模式


模式就是一系列通用问题的方案,例如jQuery的$选择器就是一个Facade模式,封装了选择器的内部实现,提供了统一的选择器接口。

反模式是需要文档记录的不好的设计,例如变量污染全局空间、使用eval不当、修改对象原型、使用docuemnt.write不当等。

创建型模式


创建对象有如下三种方式:

var obj = {};
var obj = Object.create(null);
var obj = new Object();

给对象添加属性有如下四种方式:

obj.key = value;
obj[key] = value;
Object.defineProperty(obj, key, {
  value: value,
  writable: true,
  enumerable: true,
  configurable: true
});
Object.defineProperties(obj, {
  key: {
    value: value,
    writable: true
  }
});

相应的,读取对象属性也有两种方式:

obj.key
obj[key]

构造器模式


典型的构造器为:

function Car(name) {
  this.name = name;
  this.toString = function() {
    return 'name = ' + this.name;
  }
}

不过上述代码有点缺点,每次构造对象时,toString方法都需要重新定义一遍,我们可以将toString方法放到原型链中。

function Car(name) {
  this.name = name;
}

Car.prototype = {
  toString: funciton() {
    return 'name = ' + this.name;
  }
};

单例模式


单例模式提供全局的访问点,在JavaScript中,单例模式有很多类型,最简单的是一个对象。

var Singleton = {
property1: key1,
  property2: key2,
  method1: function() {
    console.log('hello, world');
  }
};

更进一步,可以使用IIFE来隐藏局部变量,只返回公有方法。

var Singleton = (function(){
  var p1 = key1;
  var p2 = key2;
    
  return {
    method1: function() {
      return p1 + p2;
    }
  };
}());

上述例子是即使初始化的,如果你只想在真正使用到该单例对象时才初始化,那么可以将初始化方法防止另一个构造函数中。

var Singleton = (function(){
  var instantiated;
    
  function init() {
    var p1 = key1;
    var p2 = key2;
        
    return {
      method1: function() {
        return p1 + p2;
      }
    };
  }
    
  return {
    getInstance: function() {
      if (!instantiated) {
        instantiated = init();
      }
      return instantiated;
    }
  };
}());

// get singleton
Singleton.getInstance.method1();

下面是单例模式的最后一个例子,这一次主要加入了一些配置文件。

var SingletonTester = (function() {
  
  function Singleton(options) {
    var instance;
    options = options || {};
    this.name = options.name;
    this.pointX = options.pointX;
  }
  
  var instance;
  
  var _static = {
    name: 'SingletonTester',
    getInstance: function(options) {
      if (instance === undefined) {
        instance = new Singleton(options);
      }
      return instance;
    }
  }
  
  return _static;
}());

var singletonTest = SingletonTester.getInstance({pointerX: 5});