本文介绍如何在JavaScript中通过命名空间封装避免多库引入时的函数冲突。详细对比两种实现方式:对象字面量定义与构造函数结合with语句,并提供具体代码示例。建议按命名空间命名JS文件,以提升代码重用性和维护效率。
JavaScript 命名空间封装:解决多库冲突与代码复用
当在同一个网页中引入超过10个JavaScript文件时,
各个JS文件中同名函数发生冲突的概率显著增加。
例如,xxx库中定义了addCssStyle方法,
yyy类库中也存在同名的addCssStyle方法,
且这两个方法的具体实现逻辑存在差异。
若同时引用这两个组件,函数冲突将导致页面行为异常,
此时进行调试和修复工作极为繁琐。若为规避冲突而放弃引用优质组件,
无疑会令人感到沮丧。
因此,在封装JavaScript组件库时,务必使用命名空间来防止冲突。
所有方法和变量均应遵循包名与类名的层级结构进行命名。
(此时编写代码的体验类似于封装Java的util方法,十分便捷)
基于此理念,我的JS库采用如下方式封装。
经过大量搜索未发现现成方案,遂自行摸索出示例代码:
(lizongbo原创!!!)
<script language="JavaScript" type="text/javascript" >
<!-- //初始化命名空间
var jscom = jscom ? jscom : {};
jscom.lizongbo = jscom.lizongbo ? jscom.lizongbo : {};
//第一种封装方法
jscom.lizongbo.util = jscom.lizongbo.util ? jscom.lizongbo.util : {
crtVersion : 'jscom.lizongbo.util version 0.0.1', //注意用逗号隔开
sayHello: function (str){
window.alert('hello : '+str +' by ' + this.getVersion()); //变量引用要加上this
},//注意用逗号隔开
getVersion :function (){
//alert(' jscom.lizongbo.util version ' + this.crtVersion);//变量引用要加上this
return this.crtVersion+' lizongbo';
} //注意不能够有逗号
}
//第二种封装方法
jscom.lizongbo.util2 =function (){};//重点是这行,它保证了下面的with调用
jscom.lizongbo.util2.crtVersion=' jscom.lizongbo.util2 version 0.0.2';
jscom.lizongbo.util2.sayHello = function(str){
with (jscom.lizongbo.util2) {//这里也是重点,不然会找不到getVersion方法。
window.alert('你好 : '+str +' by ' + getVersion());//这种方法不用加this
}
};
jscom.lizongbo.util2.getVersion = function(){
with (jscom.lizongbo.util2) {//这里也是重点,不然会找不到crtVersion变量。
return crtVersion+' lizongbo2';
}
};
var vutil1= jscom.lizongbo.util; //和java的import差不多好用
vutil1.sayHello('lizongbo'); //第一种调用
var vutil2= jscom.lizongbo.util2;
vutil2.sayHello('lizongbo');//第二种调用
//-->
</script>
将上述代码复制到网页中即可查看效果。
对比两种实现方式,现有代码按第二种方式进行改造最为便捷。
若再将JS文件按命名空间规则命名,操作将更加简便。
例如
<script type="text/javascript" src="/commons/scripts/jscom.lizongbo.util1.js"></script>
<script type="text/javascript" src="/commons/scripts/jscom.lizongbo.util2.js"></script>
只要所有库均按此规范编写,便无需再担忧引入多个JS文件后的函数冲突问题。