JavaScript 命名空间 使用介绍

 更新时间:2013年08月29日 00:20:06   作者:  
使用JavaScript实现命名空间就没有这么舒服了,Javascript只有函数作用域,什么块儿啊、神马文件啊统统都认为是一个命名空间的,有时候因为一些重名问题导致的错误让人莫名其妙,难以调试解决

使用过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是怎么做的?欲知后事如何,且听下回分解。

相关文章

  • js 中的console使用示例详解

    js 中的console使用示例详解

    console 是 JavaScript 提供的一个全局对象,常用于调试和日志记录,它包含一组方法,用于在控制台中打印消息、显示数据以及调试程序,本文介绍js 中的console使用示例,感兴趣的朋友一起看看吧
    2024-12-12
  • 浅谈layui分页控件field参数接收对象的问题

    浅谈layui分页控件field参数接收对象的问题

    今天小编就为大家分享一篇浅谈layui分页控件field参数接收对象的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 基于JS实现EOS隐藏错误提示层代码

    基于JS实现EOS隐藏错误提示层代码

    本文给大家分享一段代码基于js实现EOS隐藏错误提示层,对eos隐藏提示层的相关知识感兴趣的朋友一起学习吧
    2016-04-04
  • JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析

    JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析

    这篇文章主要介绍了JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作,结合实例形式分析了JavaScript针对HTML DOM 元素 (节点)的新增,编辑,删除相关操作技巧与使用注意事项,需要的朋友可以参考下
    2020-03-03
  • 通过JS运行机制的角度说说作用域

    通过JS运行机制的角度说说作用域

    这篇文章主要给大家介绍了如何通过JS运行机制的角度说说作用域的相关资料,文中通过图文介绍的非常详细,对大家的学习或者使用JS作用域具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • 创建与框架无关的JavaScript插件

    创建与框架无关的JavaScript插件

    这篇文章主要介绍了创建与框架无关的JavaScript插件,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下
    2020-12-12
  • Three.js+React使二维图片呈现3D效果

    Three.js+React使二维图片呈现3D效果

    这篇文章主要为大家介绍了如何利用Three.js+React技术栈,将二维漫画图片转化为三维视觉效果。文中的实现方法讲解详细,需要的可以参考一下
    2022-02-02
  • JavaScript实现随机替换图片的方法

    JavaScript实现随机替换图片的方法

    这篇文章主要介绍了JavaScript实现随机替换图片的方法,涉及javascript中Math.random方法的灵活运用,需要的朋友可以参考下
    2015-04-04
  • easyui combobox开启搜索自动完成功能的实例代码

    easyui combobox开启搜索自动完成功能的实例代码

    下面小编就为大家带来一篇easyui combobox开启搜索自动完成功能的实例代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • JavaScript常用数组去重实战源码

    JavaScript常用数组去重实战源码

    本文给大家分享js常用8种数组去重实战源码,针对每种方法通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2021-07-07

最新评论