javascript Module模式

来源:互联网 发布:b2c网上商城源码 编辑:程序博客网 时间:2024/05/23 12:20

参考:汤姆大叔的博文。

先看一个例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>无标题文档</title></head><script type="text/javascript">var Calculator=function(){return { //返回一个key-value的object对象add:function(x,y){return x+y;},sub:function(x,y){return x-y;}}}var cal=new Calculator();alert(cal.add(1,2)+" "+cal.sub(2,1));</script><body></body></html>
这样每次要调用add方法时候都需要new一个Calculator对象。

匿名闭包:函数内部的代码一直在闭包内,在整个运行周期内,该闭包都保证了内部代码处于私有化状态。jQuery就是采用这种形式。下面是jQuery的代码:

(function( window, undefined ) {    //jQuery代码})(window);

jQuery通过定义了一个匿名函数,创建了一个私有的命名空间,该命名空间上的变量和方法不会破坏全局的命名空间,同时也保证了jQuery创建的变量不会与导入其他的js程序创建的变量发生冲突。

上面的代码可以写成另外一种方式:

(function( window, undefined ) {    //jQuery代码}(window));

参照上面这种方式修改第一个四则运算的代码,这个时候就不用通过new的方式调用add方法了,因为当使用这种方式后函数会自执行。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>无标题文档</title></head><script type="text/javascript">var Calculator=(function(){return {add:function(x,y){return x+y;},sub:function(x,y){return x-y;}}}());alert(Calculator.add(1,2)+" "+Calculator.sub(2,1));</script><body></body></html>

隐式全局变量:

一个变量不管有没有用过,JavaScript解释器会反向遍历作用域链来查找整个变量的var声明,如果没有找到var,解释器则假定该变量是全局变量,如果该变量用于了赋值操作的话,之前如果不存在的话,解释器则会自动创建它,这种特性就叫做隐式全局变量。

有了这种特性,这就是说在匿名闭包里使用或创建全局变量非常容易,不过比较困难的是,代码比较难管理,尤其是阅读代码的人看着很难区分哪些变量是全局的,哪些是局部的。

这时可以将全局变量作为一个参数然后传递到匿名函数中使用,如jQuery中的window参数,这个时候通过传入window变量,使得window由全局变量变成了局部变量,好处有两个:

1、根据隐式全局变量的特性,JavaScript解释器不用将作用域链回退到顶层作用域,可以更快的访问window;

2、查看jQuery的压缩版min.js包,会看到将window作为参数传入可以将压缩代码进行优化(将window优化成为a)。

(function(a,b){    //jQuery压缩代码})(window); 

如果我不仅仅想使用全局变量,而且想声明全局变量,这时我们可以通过匿名函数的返回值来返回这个全局变量。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>无标题文档</title></head><script type="text/javascript">var Introduce=(function(){var my={};var privateName="xuzengqiang"; //私有名称,外部不能直接访问my.name=privateName;function sayHello(name) //私有方法,外部不能直接访问{alert("我叫"+name);}my.say=function(){sayHello(my.name); //但是这里可以调用内部处理的方法}return my;}());//Introduce.sayHello();  //错误,为私有方法Introduce.say(); alert(Introduce.name); //可以直接调用</script><body></body></html>






0 0