JavaScript 命名空间

本文介绍JavaScript中命名空间的概念与实现方法,通过实例演示如何避免命名冲突,并提供一个简易的JavaScript库示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 在本文中,我们将探讨如何通过 Vue.js 实现一个带有动画效果的“回到顶部”功能。Vue.js 是一款用于构建用户界面的流行 JavaScript 框架,其组件化和响应式设计让实现这种交互功能变得十分便捷。 首先,我们来分析 HTML 代码。在这个示例中,存在一个 ID 为 back-to-top 的 div 元素,其中包含两个 span 标签,分别显示“回到”和“顶部”文字。该 div 元素绑定了 Vue.js 的 @click 事件处理器 backToTop,用于处理点击事件,同时还绑定了 v-show 指令来控制按钮的显示与隐藏。v-cloak 指令的作用是在 Vue 实例渲染完成之前隐藏该元素,避免出现闪烁现象。 CSS 部分(backTop.css)主要负责样式设计。它首先清除了一些默认的边距和填充,对 html 和 body 进行了全屏布局,并设置了相对定位。.back-to-top 类则定义了“回到顶部”按钮的样式,包括其位置、圆角、阴影、填充以及悬停时背景颜色的变化。此外,与 v-cloak 相关的 CSS 确保在 Vue 实例加载过程中隐藏该元素。每个 .page 类代表一个页面,每个页面的高度设置为 400px,用于模拟多页面的滚动效果。 接下来是 JavaScript 部分(backTop.js)。在这里,我们创建了一个 Vue 实例。实例的 el 属性指定 Vue 将挂载到的 DOM 元素(#back-to-top)。data 对象中包含三个属性:backTopShow 用于控制按钮的显示状态;backTopAllow 用于防止用户快速连续点击;backSeconds 定义了回到顶部所需的时间;showPx 则规定了滚动多少像素后显示“回到顶部”按钮。 在 V
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值