zoukankan      html  css  js  c++  java
  • JavaScript模式读书笔记 第5章 对象创建模式

    1,命名空间模式  namespace
      <script>
    var myApp = {};//通过全局变量来实现命名空间
    maApp.Parent = function (){
     
    };
    myApp.Child = function(){
    };
      </script>

        通用命名空间函数
      <script>
    //不安全代码
    var myApp = {};
    //安全代码
    if(typeof myApp === "undefined"){
    var myApp = {};
    }
    //或者使用更短的语句
    var myApp = myApp || {};
      </script>
     使用命名空间函数

      <script>
    myApp.namespace("myApp.modules.module2");
    //等同于如下代码
    var myApp = {
    modules : {
    module2:{}
    }
    };
      </script>

    <script>
    var myApp = myApp || {};
     
    myApp.namespace = function(ns_string){
     
    var parts = ns_string.split('.'), parent = myApp, i;
     
    if(parent[0] === "myApp"){
    parts = parts.slice(1);
    }
     
    for(i = 0; i < parts.length; i++){
    if(typeof parent[parts[i]] === "undefined"){
    parent = parent[parts[i]];
    }
    }
    return parent;
    };
     
    var modules2 = myApp.namespace("myApp.modules.module2");
    console.log(modules2 === myApp.modules.module2);
     
    myApp.namespace("modules.module2");
      </script>

    2,声明依赖关系
        js库通常是模块化且依据命名空间组织的。
      var myFunction = function(){ var event = YAHOO.util.event, dom = YAHOO.util.Dom; }

    3,私有属性和方法
        JS并没有特殊的语法来表示私有。JS中所有对象的成员是公共的。
        
    var myObj = {
      
    myProp : 1,
       getPro: function(){
     
    return this.myProp;
      }
     
    };
    console.log(myObj.myProp);
    console.log(myObj.getPro());
        但是可以使用闭包实现成员私有化。
       
      <script>
    function Gadget(){
    //私有成员
    var name = "iPoid";
    //共有函数
    this.getName = function(){
    return name;
    };
    }
     
    var toy = new Gadget();
     
    console.log(toy.name);//undefined
    console.log(toy.getName);//iPoid 
      </script>
     私有性失效:因为涉及到引用传值,如果传递私有属性给外部,则外部可直接访问私有属性,如下:
       
     <script>
    function Gadget(){
    //私有成员
    var specs = {
    screen_width: 320,
    screen_hight: 650,
    color: 'RED'
    };
    //共有函数
    this.getSpecs = function(){
    return specs;
    };
    }
     
    var toy = new Gadget(),
    specs = toy.getSpecs();
    specs.color = "GUESS";
    console.log(specs.screen_width);//320
    console.log(specs.color);//GUESS
     
    console.dir(toy.getSpecs());
     
      </script>
    4,对象字面量以及私有属性
      
        <script>
    var myObj = (function(){
    var name = "name";
     
    return {
    getName: function(){
    return name;
    }
    };
    }());
    console.log(myObj.getName());//name
      </script>
    5,原型和私有性
        通过prototype可以动态的给对象添加属性和方法。
       
      <script>
    function Gadget(){
    var name = "Ipod";
     
    this.getName = function(){
    return name;
    };
    }
     
    Gadget.prototype = (function(){
    var browser = "others";
     
    return{
    getBrowser: function(){
    return browser;
    }
    };
    }());
     
    var toy = new Gadget();
    console.log(toy.getName());//name
    console.log(toy.getBrowser());//others
      </script>

    6,将私有方法揭示为公共方法
        通过全局变量可以将匿名函数的私有方法公开。
      
      <script>
     var myArray;
     
     (function(){
    var astr = "[object Array]",
    toString = Object.prototype.toString;
     
    function isArray(s){
    return toString.call(s) === astr;
    }
     
    function indexOf(haystack, needle){
    var i = 0, 
    max = haystack.length;
    for(; i < max; i+= 1){
    if(haystack[i] === needle){
    return i;
    }
    }
    return -1;
    }
    myArray = {isArray: isArray, 
    indexOf: indexOf,
    inArray: indexOf};
     
    console.log(myArray.isArray([1, 2]));//true
    console.log(myArray.isArray({0 : 1}));//false
    console.log(myArray.indexOf(["a", "b"], "a"));//0
    console.log(myArray.indexOf(["a", "b"], "d"));//-1
     }());
     
    console.log(myArray.indexOf(["a", "b"], "a"));//0
    console.log(myArray.indexOf(["a", "b"], "d"));//-1
      </script>
    7,模块模式
        模块模式通过命名空间,完成函数变量定义和使用。
      
    <script>
    myApp.namespace("myApp.util.array");
    myApp.util.array = (function(){
    var uobj = myApp.util.object, 
    ulang = myApp.util.lang,
    array_string = "[object Array]",
    ops = Object.prototype.toString;
    return {
    inArray: function(needle, haystack){
    for(var i = 0, max = haystack.length; i < max; i+= 1){
    if(haystack[i] === needle){
    return true;
    }
    }
    },
     
    isArray: function(s){
    return ops.call(a) === array_string;
    }
    };
     
     
    }());
      </script>
     通过揭示模式暴漏想暴漏的方法。
      
    <script>
    myApp.namespace("myApp.util.array");
    myApp.util.array = (function(){
    var uobj = myApp.util.object, 
    ulang = myApp.util.lang,
    array_string = "[object Array]",
    ops = Object.prototype.toString;
    inArray: function(needle, haystack){
    for(var i = 0, max = haystack.length; i < max; i+= 1){
    if(haystack[i] === needle){
    return true;
    }
    }
    },
     
    isArray: function(s){
    return ops.call(a) === array_string;
    };
     
    return {
    isArray: isArray,
    indexOf: inArray
    };
    }());
      </script>
    创建构造函数的模块
        
     <script>
    myApp.namespace("myApp.util.array");
    myApp.util.array = (function(){
    var uobj = myApp.util.object, 
    ulang = myApp.util.lang;
     
    Constr;
     
    Constr = function(o){
    this.elements = this.toArray(o);
    };
     
    //共有API原型
    Constr.prototype = {
    constructor: myApp.util.array,
    version: "2.0",
    toArray: function(obj){
    for(var i = 0, a= [], len = obj.length; i < len; i+= 1){
    a[i] = obj[i];
    }
     
    return a;
    }
    };
     
    //返回要分配给新命名空间的构造函数
    return Constr;
    });
     
    var arr = new myApp.util.array([obj]);
      </script>
    8,将全局变量导入到模块中
         
    <script>
    MYAPP.util.module = (function(app, global){
    //
    }(MYAPP, this));
      </script>
    9,沙箱模式
        沙箱模式解决命名空间模式的如下特点:
        -1,对单个全局变量的依赖变成了对应用程序的全局变量依赖。在命名空间模式中,是没有办法使用同一个应用程序或库的两个版本在同一页面中,因为这两者都需要同一个全局符号名。
        -2,对这种以点分割的名字来说,需要输入更长的字符,同时解析时需要更长的时间。如:myapp.a.b.c.d
    沙箱模式提供了一个可用于模块运行的环境,且不会对其他模块和沙箱造成影响。
    10,全局构造函数
           最基础的使用如下图所示
       <script>
    new Sandbox(function(box){
    //write your code
    });
      </script>
        通过以下两种方式扩展属性:
        -1,在创建对象的时候不实用new操作符。
        -2,Sandbox()狗仔函数可以接受一个额外的配置参数,其中改参数制订了对象事例所需要的模块名。
          
    <script>
    Sandbox(['ajax', 'event'], function(box){
    //your code
    });
      </script>
    或者,
    <script>
    Sandbox('ajax', 'event', function(box){
    //your code
    });
      </script>
    一个沙箱中可以继续使用一个沙箱模块。
      
    <script>
    Sandbox('dom', 'event', function(box){
    //your code 
    Sandbox('ajax', function(box){
    //your cide 
    })
     
    //此处无法获取ajax
    });
      </script>
    11,增加模块
         
    <script>
    Sandbox.modules = ();
    Sandbox.modules.dom = function(box){
    box.getElement = function(){};
    box.getStyle = function(){};
    box.foo = "bar";
    };
    Sandbox.modules.event = function(box){
    //如果需要,可以通过如下语句访问Sandbox原型
    //box.constructor.prototype.m = "mmmmm";
     
    box.attachEvent = function(){};
    box.dettachEvent = function(){};
    };
    Sandbox.modules.ajax = function(box){
    box.makeRequest = function(){};
    boix.getResponse = function(){};
    }
      </script>
    12,实现构造函数
        
    <script>
    function Sandbox(){
    //将参数转为一个数组
    var args = Array.prototype.slice.call(arguments), 
      //最后一个参数是回调函数
    callback = args.pop(),
    //模块可以做为一个数组传递,或作为单独的参数传递
    modules = (args[0] && typeof args[0] === "string") ? args : args[0],
    i;
    //确保该函数做为狗仔函数被调用
    if(! (this instanceof Sandbox)){
    return new Sandbox(modules, callback);
    }
     
    //向this添加属性
    this.a = 1;
    this.b = 2;
     
    //向this对象添加模块
    //不制定模块或指定“*”都表示使用所有模块 
    if(!modules || modules === "*"){
    for(i in Sandbox.modules){
    if(Sandbox.modules.hasOwnProperty(i)){
    moduls.push(i);
    }
    }
    }
    //初始化模块
    for(i = 0; i < modules.length; i+= 1){
    Sandbox.modules[[moduls[i]]](this);
    }
     
    callback(this);
    }
     
    Sandbox.prototype = {
    name: "My Application",
    version: "1.00",
    getName: function(){
    return this.name;
    }
    };
      </script>
        以上代码的关键部分:
        -1,存在一个类型的检查语句,检查this是否为Sandbox的实例。
        -2,可以在该构造函数中将一些属性添加到this中。
        -3,所需的模块可以魔窟名称数组的形式传递。

    13,公有静态成员
        
     <script>
      //构造函数
    var Gadget = function(){};
    //静态方法
    Gadget.isShiny = function(){
    return "Static Method!";
    };
     
    //原型添加方法
    Gadget.prototype.setPrice = function(price){
    this.price = price;
    };
     
    console.log(Gadget.isShiny());//Static Method! 
     
    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());//Static Method!
      </script>

    14,私有静态成员
        -1,以同一个构造函数创建的所有对象共享该成员
        -2,构造函数外部不可访问该成员。
     
    <script>
    var Gadget = (function(){
    var counter = 0;
     
    return function(){
    console.log(counter += 1);
    }
    }());//立即执行
     
    var g1 = new Gadget();//1
    var g2 = new Gadget();//2
      </script>
    15,链模式
        如:
    myObj.method1("11").method2("w").method3();
    16,method方法
        
    var Person = function(name){
    this.name = name;
    }.method("getName", function(){
    return this.name;
    });

















    欢迎转载,但转载请注明原文链接[博客园: http://www.cnblogs.com/jingLongJun/]
    [CSDN博客:http://blog.csdn.net/mergades]。
    如相关博文涉及到版权问题,请联系本人。
  • 相关阅读:
    Java学习——字符串
    Java学习——字符串
    【费马小定理+快速幂取模】ACM-ICPC 2018 焦作赛区网络预赛 G. Give Candies
    【费马小定理+快速幂取模】ACM-ICPC 2018 焦作赛区网络预赛 G. Give Candies
    Java学习——Eclipse下载,java配置,新建,输入输出
    Java学习——Eclipse下载,java配置,新建,输入输出
    python使用scikit-learn计算TF-IDF
    scanf,printf函数细节
    UVA 4855 Hyper Box
    poj 2001 Shortest Prefixes(字典树)
  • 原文地址:https://www.cnblogs.com/jingLongJun/p/4491078.html
Copyright © 2011-2022 走看看