码迷,mamicode.com
首页 > 其他好文 > 详细

module模式小记

时间:2015-09-02 10:42:25      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

当我们以一个通常的写法来写一个构造函数的时候(通过new 调用的函数) 它里面的属性和方法对外界是可见的

     function Person() {
            this.name = "haha";

            this.sayName = function(){
                return this.name;
            }

       return this; }
var p1 = new Person(); console.log(p1.sayName());//haha console.log(p1.name);//haha

     p1.name = ""ha";
     console.log(p1.sayName());//ha

这里的Person定义了一个name属性和一个sayName方法 通过生成的对象能调用相应的方法 但是发现生成的对象也能直接调用name属性(这并没有任何奇怪 因为name本身就是生成对象的属性) 这样的模式不能达到我们实现私有属性的目的

要实现私有属性 ,就要通过匿名闭包

(function(){
            //所用的变量和function都在这里声明,作用域也只能存在这个闭包中,这里的代码仍然能访问外部的作用域,是作用链的问题

        }());

我们在匿名闭包中声明变量和function 这样作用域只存在这个闭包中,外界无法访问 ,但是这里的代码可以通过作用链查找到外面的变量 

下面我们来实现一个简单的例子(简单的module模式)

var module = (function(){
            var my = {},
                id = 123;

            function getId() {
                return id;
            }//私有变量和function在这里声明,在外边是不能访问到的

            my.Id = id;
            my.getPrivateId = function() {
                return getId();
            }

            return my; //只能通过返回的my来访问内部的私有变量和function
        }());

        console.log(module.Id);
        console.log(module.getPrivateId());
   

当我们有新的需求要扩展我们的module的时候(项目组的好几个人都要扩展) 首先他要引入之前的module文件 也就是上面这段例子,然后在进行扩展(这样也实现了module的多人开发)

var module = (function(my){
            my.say = function() {
                return "扩展了";
            }

            return my;
        }(module));

        console.log(module.say()); //扩展了

这里实现的方式是将之前的module传入匿名闭包函数 ,对它的相应的功能进行添加,同时还是保持了之前私有变量和function的私有性,这里的var并不是必须的(因为之前已经声明了module 这是一种紧耦合的扩展模式),这种模式对文件的加载顺序有要求

如果不对文件的加载顺序有要求,也就是松耦合的扩展模式 可以这样实现

var module = (function(my){
            //扩展

            return my;
        }(module || {}))

当我们为匿名闭包传递参数的时候传递的是 module || {} 也就是当module不存在的时候 ,我们去创建它 这就不需要我们文件的加载顺序有要求了,这是一种松耦合的扩展模式,这种模式下也有一定的限制,就是不能重写一些属性和方法 (因为不用加载顺序,当我们想重写的时候,相应的属性和方法有可能不存在,就不存的重写这个说法,也就是新的定义)并且这里的var必须写,(因为其他的人想读取你的文件的时候会读取不到)

紧耦合的模式下虽然限制了加载的顺序,但是能提供给我们重写属性方法的机会

var module = (function(){
            var my = {};
            var id = 123;
            function a() {
                return "a";
            };


            my.b = function(){
                return "this is old func";
            }
            return my;
        }());
        console.log(module.b());//this is old func
        var module = (function(my){
            var oldfunc = my.b;

            my.b = function() {
                return "this is new func";
            }
            my.oldfunc = oldfunc;
            return my;
        }(module));

        console.log(module.b()); //this is new func
        console.log(module.oldfunc());//this is old func

上面是一个完成了例子 重写了之前定义的b方法 并且通过将之前的方法重新添加到module中,也可以访问之前的方法

子模块实现方式 当我们需求在上面的module下实现一个子模块的时候 我们可以这样

module.test = (function(){
            var name = "aa",
                my = {};


            my.sayName = function(){
         //console.log(mudule.b()); //子模块能调用父模块的方法 他们在一个命名空间
return name; } return my; }()); console.log(module.test.sayName());//aa

这样就实现了一个子模块 

在javascript设计模式的书中,提供了一种创建命名空间的方式,上面的创建子模块的方式 子模块和父模块存在一个命名空间(有些时候我们想要实现的是两个module存在不同的命名空间 ) 下面给出书中的实现方式

首先我们需要一个创建命名空间的通用函数 

    var MySpace = MySpace || {};
        MySpace.namespace = function(ns_string){
            var parts = ns_string.split(‘.‘),
                parent = MySpace,
                i = 0,
                length = 0;

            if(parts[0] === "MySpace") {
                parts = parts.slice(1);
            }

            for(i = 0;length = parts.length,i < length;i += 1) {
                if(typeof parent[parts[i]] === "undefined") {
                    parent[parts[i]] = {};
                }

                parent = parent[parts[i]];
            }

            return parent;

        }

通过上面的函数我们就能在相应的命名空间里创建我们的module了

MySpace.namespace(‘MySpace.modules.test‘);


        MySpace.modules.test = (function(){
            var name = "haha",
                my = {};

            my.sayName = function(){
                return  name;
            }

            return my;
        }());
MySpace.namespace(‘MySpace.modules.a‘);//在同样的层级创建其他的module
 

参考 javascript设计模式

blog http://www.cnblogs.com/TomXu/archive/2011/12/30/2288372.html 

 

 

module模式小记

标签:

原文地址:http://www.cnblogs.com/tiantianwaigong/p/4777266.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!