zoukankan      html  css  js  c++  java
  • Javascript对象的创建模式 -- 深入了解Javascript

    /*
        一、模式1:命名空间(namespace)
        优点:减少全局命名所需的数量,避免命名冲突或过度
    */
    // 更简洁的方式
    var MYAPP = MYAPP || {};
    
    //定义通用方法
    MYAPP.namespace = function (ns_string) {
        var parts = ns_string.split('.'),
            parent = MYAPP,
            i;
    
        // 默认如果第一个节点是MYAPP的话,就忽略掉,比如MYAPP.ModuleA
        if (parts[0] === "MYAPP") {
            parts = parts.slice(1);
        }
    
        for (i = 0; i < parts.length; i += 1) {
            // 如果属性不存在,就创建
            if (typeof parent[parts[i]] === "undefined") {
                parent[parts[i]] = {};
            }
            parent = parent[parts[i]];
        }
        return parent;
    };
    /*
        二、模式2:定义依赖
    */
    var myFunction = function () {
        // 依赖模块
        var event = YAHOO.util.Event,
            dom = YAHOO.util.dom;
    
        // 其它函数后面的代码里使用局部变量event和dom
    };
    /*
        三、模式3:私有属性和私有方法 --通过闭包来实现
    */
    function Gadget() {
        var name = "123";//私有属性
        //公有函数
        this.getName = function () {
            return name;
        }
    }
    var myObj; // 通过自执行函数给myobj赋值
    (function () {
        var name = "123";//自由对象
        myObj = {
            //授权方法
            getName: function () {
                return name;
            }
        }
    }());
    /*
        四、模式4:Revelation模式  --隐藏私有方法的模式
        在外部先声明一个变量,然后在内部给变量赋值公有方法
    */
    var myarray;
    (function () {
        function isFunc() {
    
        }
        //通过赋值的方式,将上面所有的细节都隐藏了
        myarray = {
            myFunc: isFunc
        };
    }());
    /*
        五、模式5:链模式
        链模式可以你连续可以调用一个对象的方法,比如obj.add(1).remove(2).delete(4).add(2)这样的形式,其实现思路非常简单,就是将this原样返回
    */
    var obj = {
        value: 1,
        increment: function () {
            return this;
        },
        add: function () {
            return this;
        }
    }
    obj.increment().add();
    /*
        六、模式6:函数语法糖
        函数语法糖是为一个对象快速添加方法(函数)的扩展,这个主要是利用prototype的特性
    */
    if (typeof Function.prototype.method !== "function") {
        Function.prototype.method = function (name, implementation) {
            this.prototype[name] = implementation;
            return this;
        };
    }
    var Person = function (name) {
        this.name = name;
    }
    .method('getName',
                function () {
                    return this.name;
                })
    .method('setName', function (name) {
        this.name = name;
        return this;
    });
    /*
        六、模式7:对象常量
        对象常量是在一个对象提供set,get,ifDefined各种方法的体现,而且对于set的方法只会保留最先设置的对象,后期再设置都是无效的,已达到别人无法重载的目的
    */
    var constant = (function () {
        var ownProp = Object.prototype.hasOwnProperty,
            // 只允许设置这三种类型的值
            allowed = {
                string: 1,
                number: 1,
                boolean: 1
            },
            consstants = {};
        return {
            set: function (name, value) {
                if (this.isDefined(name)) {
                    return false;
                }
                if (!ownProp.call(allowed, typeof value)) {
                    return false;
                }
                constants[name] = value;
                return true;
            },
            get: function () {
                return null;
            },
            isDefined: function (name) {
                return ownProp.call(constants, name);
            }
        }
    }());
    /*
        六、模式8:沙盒模式
        沙盒(Sandbox)模式即时为一个或多个模块提供单独的上下文环境,而不会影响其他模块的上下文环境,比如有个Sandbox里有3个方法event,dom,ajax,在调用其中2个组成一个环境的话,和调用三个组成的环境完全没有干扰
    */
    function Sandbox() {
        var args = Array.prototype.slice.call(arguments), //获取函数参数
            callback = args.pop(),//最后一个参数,并从args除去
            modules = (args[0] && typeof args[0] === "string") ? args : args[0], //除去最后一个参数,都为要选择的模块
            i;
    
        //强制使用new修饰符
        if (!(this instanceof Sandbox)) {
            return new Sandbox(modules, callback);
        }
        // 向this对象上添加模块
        // 如果没有模块或传入的参数为 "*" ,则以为着传入所有模块
        if (!modules || modules == '*') {
            modules = [];
            for (i in Sandbox.modules) {
                if (Sandbox.modules.hasOwnProperty(i)) {
                    modules.push(i);
                }
            }
        }
    
        // 初始化需要的模块
        for (i = 0; i < modules.length; i += 1) {
            Sandbox.modules[modules[i]](this);
        }
    
        // 调用 callback
        callback(this);
    }
    Sandbox.modules = {};
    
    Sandbox.modules.dom = function (box) {
        box.getElement = function () {
        };
        box.getStyle = function () {
        };
        box.foo = "bar";
    };
    
    Sandbox.modules.event = function (box) {
        // access to the Sandbox prototype if needed:
        // box.constructor.prototype.m = "mmm";
        box.attachEvent = function () {
        };
        box.detachEvent = function () {
        };
    };
    
    Sandbox.modules.ajax = function (box) {
        box.makeRequest = function () {
        };
        box.getResponse = function () {
        };
    };
    // 调用方式
    Sandbox(['ajax', 'event'], function (box) {
        console.log(typeof (box.foo));
        // 没有选择dom,所以box.foo不存在
    });
    
    Sandbox('ajax', 'dom', function (box) {
        console.log(typeof (box.attachEvent));
        // 没有选择event,所以event里定义的attachEvent也不存在
    });
    
    Sandbox('*', function (box) {
        console.log(box); // 上面定义的所有方法都可访问
    });
    /*
        六、模式9:静态成员
        静态成员(Static Members)只是一个函数或对象提供的静态属性,可分为私有的和公有的
    */
    //  1. 公有静态函数
    // 构造函数
        var Gadget = function () {
        };
    
        // 公有静态方法
        Gadget.isShiny = function () {
            return "you bet";
        };
        // 原型上添加的正常方法
        Gadget.prototype.setPrice = function (price) {
            this.price = price;
        };
        // 调用静态方法
        console.log(Gadget.isShiny()); // "you bet"
    
        // 创建实例,然后调用方法
        var iphone = new Gadget();
        iphone.setPrice(500);
        console.log(typeof Gadget.setPrice); // "undefined"
        console.log(typeof iphone.isShiny); // "undefined"
        Gadget.prototype.isShiny = Gadget.isShiny;
        console.log(iphone.isShiny()); // "you bet"
    //  2. 私有静态函数 --利用闭包特性实现
    //  a.第一种实现方式:
        var Gadget = (function () {
            // 静态变量/属性
            var counter = 0;
    
            // 闭包返回构造函数的新实现
            return function () {
                console.log(counter += 1);
            };
        }()); // 立即执行
        var g1 = new Gadget(); // logs 1
        var g2 = new Gadget(); // logs 2
        var g3 = new Gadget(); // logs 3
    //  b.第二种方式:
        var Gadget = (function () {
            // 静态变量/属性
            var counter = 0,
                NewGadget;
    
            //新构造函数实现
            NewGadget = function () {
                counter += 1;
            };
    
            // 授权可以访问的方法
            NewGadget.prototype.getLastId = function () {
                return counter;
            };
    
            // 覆盖构造函数
            return NewGadget;
        }()); // 立即执行
    
        var iphone = new Gadget();
        iphone.getLastId(); // 1
        var ipod = new Gadget();
        ipod.getLastId(); // 2
        var ipad = new Gadget();
        ipad.getLastId(); // 3
  • 相关阅读:
    查询避免Unknown column ‘xxx’ in ‘where clause
    Spring依赖循环:The dependencies of some of the beans in the application context form a cycle
    POJ(北京大学)刷题导航
    ACM使用Java提交总是超时的解决方法
    申请了服务器,建立了新博客。 不在用这个了。
    jeecg数据库添加字段后表单的修改
    jeecg普通表和数据字典的关联
    jeecg添加滚动图
    jeecg定时任务的bug记录
    classpath究竟是指哪里?
  • 原文地址:https://www.cnblogs.com/ruanyifeng/p/4684140.html
Copyright © 2011-2022 走看看