最开始写javascript脚本的时候,总是直接把函数卸载每个aspx页面上,这样代码很乱,不便于管理,也不好维护。本文记录了学习javascript设计模式的一些知识。

1.创建型模式

javascript里面有3中常用的创建对象的方式:

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

有4种给对象添加key和value的方式:

//兼容ECMAScript 3 
// 1. 小圆点语法
newObject.someKey = 'Hello World'; // Write properties
var key = newObject.someKey ; // Access properties

// 2. 方括号语法
newObject['someKey' ] = 'Hello World' ; // Write properties
var key = newObject['someKey' ]; // Access properties

// 仅兼容ECMAScript 5 
// 3. Object.defineProperty
Object.defineProperty (newObject, "someKey", {
     value: "for more control of the property's behavior" ,
     writable: true ,
     enumerable: true ,
     configurable: true
});

// 4. Object.defineProperties
Object.defineProperties (newObject, {
     "someKey" : {
          value: "Hello World" ,
          writable: true
     },
     "anotherKey" : {
          value: "Foo bar" ,
          writable: false
     }
});

2.构造器模式

这里,toString()方法的一个单独实例,将被所有Car对象共享。

function Car( model, year, miles) {
     this .model = model;
     this .year = year;
     this .miles = miles;
}

注意,这里我们使用Object.prototype.newMethod而不是Object.prototype,是为了避免重新定义prototype对象。

Car .prototype .toString = function () {
     return this .model + " has done " + this .miles + " miles";
};
var civic = new Car("Honda Civic", 2009, 20000);
var mondeo = new Car("Ford Mondeo", 2010, 5000);
console .log (civic .toString ());

3.单例模式

var Singleton = (function () {
     var instantiated;
     function init() {
          // 这里返回单实例
          return {
               publicMethod: function () {
                    console.log ('hello world' );
               },
               publicProperty: 'test'
          };
     }
     return {
          getInstance: function () {
               if (! instantiated) {
                    instantiated = init ();
               }
               return instantiated;
          }
     };
})();
// 调用公共方法变得非常简单:
Singleton.getInstance ().publicMethod ();

下面是使用单例模式的例子

var SingletonTester = (function () {
     // options: an object containing configuration options for the singleton
     // e.g var options = { name: 'test', pointX: 5};
     function Singleton( options) {
      //给配置项赋值,如果没有传递参数进来,则赋值一个空的对象
          options = options || {};
          //设置name参数
          this.name = 'SingletonTester';
          //设置pointX的值
          this.pointX = args.pointX || 6;
          //设置pointY的值
          this.pointY = args.pointY || 10;
     }
     // 这里是实例持有者
     var instance;
     // 这里模拟静态变量和方法
     var _static = {
          name: 'SingletonTester' ,
          // 这里获取实例的方法,它返回一个对象的单一实例
          getInstance: function (options) {
               if (instance === undefined) {
                    instance = new Singleton(options );
               }
               return instance;
          }
     };
     return _static;
})();
var singletonTest = SingletonTester. getInstance({pointX: 5});
console.log (singletonTest .pointX ); // 输出 5

4.模块模式

对象字面量
在对象字面量表示法里面,对象被描述成由一对花括号包围的,由冒号分割的名值对集合,下面是用对象字面量定义的复杂对象:

var myModule = {
     myProperty: 'someValue' ,
     // 对象字面量可以包含属性和方法
     // 这里为了配置定义了另一个对象
     myConfig: {
          useCaching: true ,
          language: 'en'
     },
     // 一个非常基本的方法
     myMethod: function () {
          console.log ('I can haz functionality?' );
     },
     // 基于当前配置输出一个值
     myMethod2: function () {
          console.log ('Caching is:' + ( this.myConfig .useCaching ) ? 'enabled' : 'disabled' );
     },
     // 覆盖当前配置
     myMethod3: function (newConfig ) {
          if (typeof newConfig == 'object' ) {
               this.myConfig = newConfig;
               console.log (this.myConfig.language);
          }
     }
};
myModule.myMethod (); // I can haz functionality
myModule.myMethod2 (); // 输出 enabled
myModule.myMethod3 ({
     language: 'fr' ,
     useCaching: false
}); // 输出 fr

模块模式

当使用模块模式时,你会发现定义一个简单的模板是一个很好的开始。下面是一个模块,包含命名空间,公共变量和私有变量:

var myNamespace = (function () {
     var myPrivateVar = 0;
     var myPrivateMethod = function (someText ) {
          console.log (someText );
     };
     return {
          myPublicVar: "foo" ,
          myPublicFunction: function (bar ) {
               myPrivateVar++;
               myPrivateMethod(bar );
          }
     };
})();

模块模式的缺点是,如果你用不同的方式访问公共成员和私有成员,当你想改变可见性的时候,你需要去修改每个用到成员的地方。
你也不能访问后续通过方法添加到对象的私有成员。
下面是使用模块模式的简单例子:

var someModule = (function () {
     // 私有属性、私有方法
     var privateMethod =function () {
          return 'Private Test';
     };
     return {
          // 公共属性
          publicVar: 10 ,
          // 公共方法
          publicMethod:function () {
               return ' Followed By Public Test ';
          },
          // 方位私有成员
          getData:function () {
               return privateMethod() + this. publicMethod() + privateVar;
          }
     }
})(); // 这里的一对括号是的匿名方法被执行并返回
someModule.getData ();

模块模式在工具和框架里面的应用

例如:如果要给store命名空间定义basket.core对象,可以通过下面两种方式实现:

第一种方式

var store = window. store || {};
if (! store[ "basket"]) {
     store.basket = {};
}
if (! store. basket[ "core"]) {
     store.basket .core = {};
}
store.basket .core = {
  // ...其余逻辑
}

第二种方式

require(["dojo/_base/customStore" ], function(store){
     // 使用 dojo.setObject()
     store.setObject ("basket.core", ( function() {
          var basket = [];
          function privateMethod() {
               console.log (basket);
          }
          return {
               publicMethod: function (){
                    privateMethod();
               }
          };
     }()));
});

5.透露模块模式

你将所有函数和变量定义为私有的,然后在模块的最后返回一个匿名对象,这个对象持有对私有变量和函数的指针,这些私有成员是你想暴露出来的。

var myRevealingModule = (function(){
     var name = 'John Smith';
     var age = 40;
     function updatePerson(){
          name = 'John Smith Updated' ;
     }
     function setPerson () {
          name = 'John Smith Set' ;
     }
     function getPerson () {
          return name;
     }
     return {
          set: setPerson ,
          get: getPerson
     };
}());
//使用例子:
myRevealingModule.get ();

 

 

 

 

 

 

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注