JavaScript 命名空间 使用介绍


Posted in Javascript onAugust 29, 2013

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

使用JavaScript就没有这么舒服了,Javascript只有函数作用域,什么块儿啊、神马文件啊统统都认为是一个命名空间的,有时候因为一些重名问题导致的错误让人莫名其妙,难以调试解决。

一个简单的例子

<input type="button" value="test" onclick="alert();"/>        <script type="text/javascript">
            function alert(){
                //.......
                test2();
                //.......
            }
            function test2(){
                alert('test2')
            }

在个例子在不同的浏览器下有不同表现,IE会报Stack over flow, Firefox会死掉。。。反正都会报错,很简单的错误,代码中自定义了一个alert函数,在alert函数中调用了test2函数,test2函数中意图调用window的alert方法,这样循环调用了,也许看了你会说这么明显的错误谁会犯,但是如果自定义的方法叫close(这个经常会出现吧),然后内部调用了一个外部文件的函数,该函数调用了window的close方法,这样错误是不是隐蔽了很多呢。

简单的命名空间

由于JavaScript没有文件作用域,不同的函数分散在不同的文件中,甚至由不同的人编写,重名的概率大大增加。是不是足够小心就可以了呢?也不尽然,还有些意外情况,比如经常会用到继承,于是写了一个没出现过的函数名extend,不料在EcmaScript5中加入了extend函数,命名空间的必要性就体现出来了。

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

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

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

简单进化

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

<input type="button" value="test" onclick="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就可以了。看起来好了很多。

美化一下

上面的写法看起来不错了,但是函数名namespace貌似是多余的了,可以美化一下

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

变成了一个立即执行的匿名函数,美化了一些,不过看起来还是怪怪的,对呀,明明是实例化的function,为什么方法定义不写到prototype中呢,匿名函数怎么写prototype。。。,还得动动脑筋

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

写几个有用的函数

querySelector和querySelectorAll是W3C提供的新的查询接口,但是名字好长,自己写个简单的,innerHTML属性也常用到,写个简单版仿jQuery的html方法

(function () {
            var _NS = function () {            }
            _NS.prototype.select = function (selector,context) {
                var context = context || document;
                return context.querySelectorAll(selector);
            }

            _NS.prototype.isArrayLike=function(obj){
                if(obj instanceof Array){
                    return true;
                }
                var length=obj.length;
                if ( obj.nodeType === 1 && length ) {
                    return true;
                }
                return false;
            }
            _NS.prototype.html = function (obj,value) {
                var isArray=this.isArrayLike(obj), i=0;
                if (typeof value == 'string') {
                    if (!isArray) {
                        obj.innerHTML = value;
                    } else {
                        var length = obj.length;
                        while (i < length) {
                            obj[i].innerHTML = value;
                            i += 1;
                        }
                    }
                } else {
                    if (!isArray) {
                        return obj.innerHTML;
                    } else {
                        return obj[0].innerHTML;
                    }
                }
            }
            window.NS = new _NS();
        })();

这样一个带有命名空间的简单JavaScript库就写成了,不用担心命名冲突了,但是用起来很不方便啊,做前端的同学都用过jQuery,人家用起来那叫一个简单,jQuery是怎么做的?欲知后事如何,且听下回分解。

Javascript 相关文章推荐
常用参考资料(手册)下载或者链接
Jul 22 Javascript
Javascript继承(上)——对象构建介绍
Nov 08 Javascript
jquery中对于批量deferred的处理方法
Jan 22 Javascript
node.js中的socket.io入门实例
Apr 26 Javascript
jQuery实现的原图对比窗帘效果
Jun 15 Javascript
js控制鼠标事件移动及移出效果显示
Oct 19 Javascript
JS实现Ajax的方法分析
Dec 20 Javascript
[原创]jQuery实现合并/追加数组并去除重复项的方法
Apr 11 jQuery
AngularJS使用$http配置对象方式与服务端交互方法
Aug 13 Javascript
vue 配置多页面应用的示例代码
Oct 22 Javascript
vue滑动吸顶及锚点定位的示例代码
May 10 Javascript
详解JS ES6编码规范
May 07 Javascript
JavaScript prototype 使用介绍
Aug 29 #Javascript
JavaScript创建对象的写法
Aug 29 #Javascript
jQuery实现用户注册的表单验证示例
Aug 28 #Javascript
Jquery实现显示和隐藏的4种简单方式
Aug 28 #Javascript
jQuery动画效果-slideUp slideDown上下滑动示例代码
Aug 28 #Javascript
jQuery动画效果-fadeIn fadeOut淡入浅出示例代码
Aug 28 #Javascript
Jquery 实现表格颜色交替变化鼠标移过颜色变化实例
Aug 28 #Javascript
You might like
那些年一起学习的PHP(一)
2012/03/21 PHP
PHP版 汉字转码的实现详解
2013/06/09 PHP
PHP微信H5支付开发实例
2018/07/25 PHP
javascript得到XML某节点的子节点个数的脚本
2008/10/11 Javascript
js表格分页实现代码
2009/09/18 Javascript
javascript 带有滚动条的表格,标题固定,带排序功能.
2009/11/13 Javascript
JS分割字符串并放入数组的函数
2011/07/04 Javascript
很棒的js Tab选项卡切换效果
2016/08/30 Javascript
js设置和获取自定义属性的方法
2016/10/20 Javascript
手机软键盘弹出时影响布局的解决方法
2016/12/15 Javascript
JavaScript常用正则函数用法示例
2017/01/23 Javascript
jQuery中ztree 点击文本框弹出下拉框的实例代码
2017/02/05 Javascript
通过button将form表单的数据提交到action层的实例
2017/09/08 Javascript
解决Jstree 选中父节点时被禁用的子节点也会选中的问题
2017/12/27 Javascript
vue实现提示保存后退出的方法
2018/03/15 Javascript
详解Vue中使用Echarts的两种方式
2018/07/03 Javascript
浅谈angular2子组件的事件传递(任意组件事件传递)
2018/09/30 Javascript
AJAX在JQuery中的应用详解
2019/01/30 jQuery
[01:11:08]Winstrike vs NB 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
[04:51]TI10典藏宝瓶Ⅱ外观视频展示
2020/08/15 DOTA
python每次处理固定个数的字符的方法总结
2013/01/29 Python
Pycharm学习教程(3) 代码运行调试
2017/05/03 Python
Python通过OpenCV的findContours获取轮廓并切割实例
2018/01/05 Python
Flask 让jsonify返回的json串支持中文显示的方法
2018/03/26 Python
Flask框架响应、调度方法和蓝图操作实例分析
2018/07/24 Python
python的一些加密方法及python 加密模块
2019/07/11 Python
Python数据分析库pandas高级接口dt的使用详解
2020/12/11 Python
英国皇家邮政海外旗舰店:Royal Mail
2018/02/21 全球购物
美国在线健康和美容市场:Pharmapacks
2018/12/05 全球购物
《蓝色的树叶》教学反思
2014/02/24 职场文书
校庆接待方案
2014/03/18 职场文书
国旗下的讲话演讲稿
2014/05/08 职场文书
经贸日语专业自荐信
2014/09/02 职场文书
建设工程授权委托书
2014/09/22 职场文书
导游词之山东八大关
2019/12/18 职场文书
Python实现制作销售数据可视化看板详解
2021/11/27 Python