JavaScript Core -- 构造命名空间封装函数

JavaScript 命名空间

使用过Java、C#的同学对命名空间非常的熟悉,在复杂的系统中会有很多的函数、对象,语言提供的、架构预定义的,这么多的函数和对象,由于编程规范要求起有实际意义的名字,难免会重名发生错误调用,而有了命名空间不但可以分类组织函数与对象,还可以形成隔离,解决重名问题。

但是在Javascript中只有函数作用域,其他的代码块、文件等都默认在一个命名空间内。有时候因为一些重名问题导致的错误让人莫名其妙,难以调试解决。

一个简单的例子

<input type="button" value="test" οnclick="alert();"/> 
function alert(){
    test2();
}
function test2(){
    alert('test2')
}

函数的循环调用导致浏览器报错。这个错误很明显,但是如果调用的函数在其它文件中,其他文件有调用了window的方法,问题则会很隐蔽。

升级:简单的命名空间

上文我们说过JavaScript有函数的作用域,所以我们可以利用这点把自定义的函数写到一个函数体内,这样函数内的变量、对象、函数就像在一个命名空间内一样和外部隔离。

<input type="button" value="test" οnclick="(new namespace()).alert();"/>   
<script type="text/javascript">
    function namespace(){
      this.alert=function(){
      console.log('test');
    }
}
</script>

这样自定义的alert方法就不会和window的alert冲突了。

升级:自动实例化

这样可以是可以,但也有问题,最大的问题在于调用方式复杂而丑陋!每次调用的时候都要实例化对象,然后调用其方法,简单修改代码让其实现自动实例化。

<input type="button" value="test" οnclick="NS.alert();"/> 
<script type="text/javascript">
(function namespace(){
    this.alert=function(){
    console.log('test');
}
window.NS=this;
})();
</script>

上面使用了“立即执行函数”的技巧,最基本的样子如下所示

(function xxx(){
    //function body 
 })();

这样写xxx函数就可以在定义完后自动执行,看起来神奇,其实上面写法可以拆成这样

function xxx(){
    //function body 
 }
xxx();

先定义一个函数,然后使用括号语法调用,而函数定义外面的一层括号只起到将函数声明转为函数定义表达式的效果(只有表达式才可以使用括号调用)。

在自定义namespace函数最后把this赋值为window的NS属性,在调用的时候直接使用NS.xx就可以了。跟进一步,在这个立即执行函数中,我们使用匿名函数,去掉多余的函数名

但是有个缺点,就是,这么写会污染wiindow对象,覆盖了window的同名函数

(function (){
    this.alert=function(){
    console.log('test');
}
window.NS=this;
})();

升级:美化一下

将方法的定义写到prototype中呢,匿名函数怎么写prototype。。。,还得动动脑筋

(function(){
var _NS=function(){}
_NS.prototype.alert=function(){
    console.log('test');
}
window.NS=new _NS();
})();

最后我们封装一个自己实现的跨浏览器的事件处理库


(function(){  
            var _NS = function (){};

            _NS.prototype = {  
              addHandler : function(element, type, handler){  
                if(element.addEventListener){  
                  element.addEventListener(type,handler,false);  
                }else if(element.attachEvent){  
                  element.attachEvent("on" + type, handler);  
                }else{  
                  elmenet["on" + type] = handler;  
                }  
      
              },  
      
              removeHandler : function(element, type, handler){  
                if(element.removeEventListener){  
                  element.removeEventListener(type, handler, false);  
                }else if(element.detachEvent){  
                  element.detachEvent("on"+type, handler);  
                }else{  
                  element["on"+type] = null;  
                }  
              },  
              //返回对event对象的引用  
              getEvent:function(event){  
                return event?event:window.event;  
              },  
              //返回事件的目标  
              getTarget:function(event){  
                return event.target||event.srcElement;  
              },  
              //取消事件的默认行为  
              preventDefault:function(event){  
                if(event.preventDefault){  
                  event.preventDefault();  
                } else{  
                  event.returnValue = false;  
                }  
              },
              alert:function(){console.log('NS alert')}
            }; 

            window.NS = new _NS() 
})()

<html lang="zh-CN">  
  <head>  
    <meta charset="utf-8"/>  
    <script src="eventUtil.js"></script>  
  </head>  
  <body>  
    <form id = "myForm">  
       <input  id="my"type="submit" value="Submit Form" />  
    </form>  
  </body>  
  <script type="text/javascript">
        var form = document.getElementById("myForm"); 
       var doSomething = function(event){  
          event = NS.getEvent(event);  
          NS.preventDefault(event); 
          NS.alert();//1
          alert("成功阻止表单的提交")  //可见,没有污染window对象,并没有覆盖window的同名alert()函数
        }
        window.NS.addHandler(form,"submit",doSomething);    
   </script>
</html>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值