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 相关文章推荐
Javascript 面向对象(三)接口代码
May 23 Javascript
js确认删除对话框效果的示例代码
Feb 20 Javascript
js中string转int把String类型转化成int类型
Aug 13 Javascript
JS实现跟随鼠标的链接文字提示框效果
Aug 06 Javascript
javascript实现动态统计图开发实例
Nov 21 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
Apr 12 Javascript
JavaScript事件详细讲解
Jun 27 Javascript
jQuery实现页面滚动时智能浮动定位
Jan 08 Javascript
JavaScrpt判断一个数是否是质数的实例代码
Jun 11 Javascript
在vue-cli 3中给stylus、sass样式传入共享的全局变量
Aug 12 Javascript
原生javascript制作的拼图游戏实现方法详解
Feb 23 Javascript
输入框跟随文字内容适配宽实现示例
Aug 14 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中curl和file_get_content的区别
2014/05/10 PHP
Yii使用CLinkPager分页实例详解
2014/07/23 PHP
关于php中一些字符串总结
2016/05/05 PHP
PHP Include文件实例讲解
2019/02/15 PHP
jquery 获取json数据实现代码
2009/04/27 Javascript
jQuery AJAX 调用WebService实现代码
2010/03/24 Javascript
JS添加删除一组文本框并对输入信息加以验证判断其正确性
2013/04/11 Javascript
js内存泄露的几种情况详细探讨
2013/05/31 Javascript
javascript类型转换示例
2014/04/29 Javascript
javascript中的__defineGetter__和__defineSetter__介绍
2014/08/15 Javascript
浅谈jQuery事件绑定原理
2015/01/02 Javascript
基于jquery实现的自动补全功能
2015/03/12 Javascript
javascript获取当前的时间戳的方法汇总
2015/07/26 Javascript
Javarscript中模块(module)、加载(load)与捆绑(bundle)详解
2017/05/28 Javascript
微信小程序 行的删除和增加操作实现详解
2019/09/29 Javascript
JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
2020/02/10 Javascript
如何通过JS实现日历简单算法
2020/10/14 Javascript
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
centos 下面安装python2.7 +pip +mysqld
2014/11/18 Python
Python实现抓取城市的PM2.5浓度和排名
2015/03/19 Python
分享一个常用的Python模拟登陆类
2015/03/29 Python
浅谈Python程序与C++程序的联合使用
2015/04/07 Python
巧用python和libnmapd,提取Nmap扫描结果
2016/08/23 Python
Scrapy框架CrawlSpiders的介绍以及使用详解
2017/11/29 Python
python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)
2017/12/20 Python
Python提取PDF内容的方法(文本、图像、线条等)
2019/09/25 Python
Python列表list常用内建函数实例小结
2019/10/22 Python
Python 实现取多维数组第n维的前几位
2019/11/26 Python
Django 实现 Websocket 广播、点对点发送消息的代码
2020/06/03 Python
Python selenium爬虫实现定时任务过程解析
2020/06/08 Python
美团网旗下网上订餐平台:美团外卖
2020/03/05 全球购物
大专生自荐信
2013/10/04 职场文书
2014年会演讲稿范文
2014/01/06 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery
Python简易开发之制作计算器
2022/04/28 Python