博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js模式第五章
阅读量:6843 次
发布时间:2019-06-26

本文共 4000 字,大约阅读时间需要 13 分钟。

命名空间模式

命名空间有助于减少程序中所需要的全局变量的数量,并且同事还有助于避免命名冲突或过长的名字前缀。我们可以创建一个全局对象,将所需的方法,属性添加到这个对象中。避免了变量全局污染。而且同样能避免与第三库的命名冲突。但是同样存在一些缺点:

  • 使用的时候,需要附加全局对象这个前缀,增加了很多重复代码。
  • 长嵌套名字意味着更长的属性解析查询时间
  • 一个全局对象意味着,任何部分的代码都能修改这个全局对象,并且影响所有调用该对象的地方。

通用命名空间函数

当我们往这个全局对象添加一个属性时,可能覆盖之前已经定义的属性了,所有我们在添加时,先得检测这个添加的属性在这个全局对象中是否已经存在。Code:

var MYAPP={};if(typeof MYAPP === "undefined"){    var MYAPP={};}var MYAPP = MYAPP || {};复制代码

这种检测一个对象好使,但是检测链式对象时,显得乏力,代码也会变得臃肿。所有我们需要设计一个可以检测链式对象的方法。Code:

MYAPP.namespace('MYAPP.modules.module2');复制代码

具体的方法实现。Code:

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 parts[i] === "undefined"){            parent[parts[i]]={};        }        parent = parent[parts[i]]    }    return parent;};复制代码

声明依赖关系

在函数或顶部声明代码所依赖的模块是一个很好的方法。因为这种声明仅涉及创建一个局部变量并使其指向所需的模块。Code:

var myFunction = function (){    var event = YAHOO.util.Event,        dom = YAHOO.util.Dom;};复制代码

这种模式有如下几个优点:

  • 显示的依赖声明表明需要的特定脚本已经包含在该页面中。
  • 在函数顶部的前期声明可以使页面维护者很容易地发现并解析依赖。
  • 解析局部变量的速度总是要比解析全局变量(YAHOO)要快,甚至比使用全局变量的嵌套属性(YAHOO.util.Dom)还要快。
  • 将第三方模块赋值给重命名的局部变量,可以拥有更好的代码量,因为我们可以使用更短的局部变量。

私有属性和方法

js中并没有特殊的语法来表示私有、保护、或公共属性和方法。因为js中所有对象的成员都是公共的。

比如我们随便创建一个对象:

var obj{    name:'nei',    run:function(){        console.log('Run');    }};obj.name //公共的,可以随便访问的。复制代码

即使使用构造函数同样如此:

function Obj(){    this.name='Nei';    this.run=function(){        console.log('run');    };}var o1=new Obj();o1.name //公共的 可以随便访问的复制代码

但是有时我们需要私有成员,所以诞生了下面的这些生成私有成员的方法。

私有成员

虽然js本身没有直接创建私有成员的方法,但是我们将变量控制在函数作用域内,保证外部访问不到它,这样一样可以创建私有成员,比如我们创建一个类,在类里面创建一个局部变量,然后用公共方法将它暴露出去,这样我们就可以创建一个私有变量,但是有个公共方法又可以访问到它。

function Nei(){    var _name='nei';    this.getName=function(){        return _name;    };}var n=new Nei();n.name   //undefinedn.getName() //"nei"复制代码

模块模式

模块模式就如下几种的集合:

  • 命名空间
  • 即时函数
  • 私有和特权成员
  • 声明依赖

沙箱模式

顾名思义就是提供了一个可用于模块运行的环境,且不会对其他模块和个人沙箱造成任何影响。

全局构造函数

命名空间模式中有一个全局对象,在沙箱模式中,我们可以设置一个全局构造函数,创建一个隔离的沙箱环境。Code:

new Sandbox(function(box)){    ....});复制代码

通过添加新特征,使这个模式更先进:

  • 通过第三章的强制new模式,可以假设在创建对象是不需要new操作符。
  • 构造函数可以接受一个额外的配置参数(或多个),其中该参数指定了对象实例所需要的模块名。希望代码是模块化的,因此绝大部分构造函数提供的功能将被限制在模块中。

静态成员

静态成员分为公有静态成员和私有静态成员

公有静态成员

所谓公有就是直接暴露在对象的属性上,外部可以访问。Code:

var Garget=function(){};//静态方法Garget.isShiny=function(){    return "you bet";};//普通方法Garget.prototype.setPrice=function(price){    this.price=price;};//可以直接调用静态方法Garget.isShiny();//输出 you bet//普通方法必须创建一个实例,实例调用var demo1=new Garget();demo1.setPrice(12);复制代码

试图以静态方法调用一个实例方法是无法正常运行的。同样,如果使用实例调用静态方法也是无法正常运行的:

typeof Garget.setPrice; // undefinedtypeof demo1.isShiny; // undefined复制代码

如果静态方法也能够被实例调用,只需重新写一个原型方法即可:

Garget.prototype.isShiny=Garget.isShiny;demo1.isShiny; // 输出 “you bet”复制代码

但是要注意这里的this指向问题,执行Garget.isShiny时,this指向Garget。执行demo1.isShiny时,this指向demo1。

我们可以用instanceof确定方法是如何被调用的:

var Garget=function(price){     this.price=price }; Garget.isShiny=function(){     var msg="you bet";     is(this instanceof Garget){         msg += ", it costs $"+ this.price + "!";     }     return msg; }; Garget.prototype.isShiny=function(){     return Garget.isShiny.call(this); }; //调用静态方法 Garget.isShiny; // 输出 "you bet" //实例调用 var d1=new Garget(12); d1.isShiny(); // 输出 "you bet,it costs $12!"复制代码

私有静态成员

私有静态成员具有如下属性:

  • 以同一个函数所创建的所有对象共享该成员
  • 构造函数外部不可访问。

利用立即执行函数实现一个简单的私有静态成员:

var Garget=(function(){    var counter=0;    return function(){        console.log(counter+=1);    };})();//多次调用var d1=new Garget(); // 1var d2=new Garget(); // 2var d3=new Garget(); // 3复制代码

现在,我们通过一个特权方法将私有属性暴露出去:

var Garget=(function(){    var counter=0,        NewGarget;    NewGarget=function(){        counter+=1;    };    //私有特权方法    NewGarget.prototype.getLastId=function(){        return counter;    };    //重写构造函数    return NewGarget;})();//测试var d1=new Garget();d1.getLastId(); // 1var d2=new Garget();d2.getLastId(); // 2var d3=new Garget();d3.getLastId(); // 3复制代码

静态属性可以包含非实例相关的方法和数据,并且不会为每个实例重新创建静态属性。

链模式

链模式最重要的一个要点,需要显示返回的this对象。

转载地址:http://spdul.baihongyu.com/

你可能感兴趣的文章
Java:基本数据类型包装类
查看>>
HDU 4917 Permutation
查看>>
pgpool-II的 FATAL: role "nobody" does not exist 错误
查看>>
jsp路径
查看>>
关于location.href几种用法的区别
查看>>
【转】拷贝构造函数/深拷贝/浅拷贝
查看>>
什么是类比估算法=自上而下的估算
查看>>
[Java] Java 打包成jar包 和 解压jar包
查看>>
模拟ajax的 script请求
查看>>
2013年小米校园招聘笔试题
查看>>
About me
查看>>
单片机第13课:串口通信---向计算机发送数据
查看>>
[译]更改自定义活动设计器上的图标
查看>>
使用WF4 状态机CTP1 进行工作流开发
查看>>
android studio 开发android app 真机调试
查看>>
[stm32] STM32的通用定时器TIMx系统了解
查看>>
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
查看>>
添加php的memcached扩展模块
查看>>
W3wp.exe占用CPU及内存资源
查看>>
Rabbitmq~对Vhost的配置
查看>>