尽量不要使用全局变量,防止环境污染和命名冲突。

所以,将全局变量放在一个命名空间下,是一个好的解决方案。

静态命名空间

1. 直接赋值

这是最基本的方法,但是它很啰嗦,你得重复书写多次变量名。好处是它很安全,并且不会产生歧义。

 var myApp = {}

 myApp.id = ;

 myApp.next = function() {
return myApp.id++;
} myApp.reset = function() {
myApp.id = ;
} window.console && console.log(
myApp.next(),
myApp.next(),
myApp.reset(),
myApp.next()
); //0, 1, undefined, 0

你可以在命名空间函数中使用this来指代对象,但是要考虑到函数被重新分配是this将指向不明。

 var myApp = {}

 myApp.id = ;

 myApp.next = function() {
return this.id++;
} myApp.reset = function() {
this.id = ;
} myApp.next(); //
myApp.next(); //
var getNextId = myApp.next;
getNextId(); //NaN whoops!

2. 使用对象字面量方法

和上面的方法相比,下面如果要改变命名空间的名字将会很方便。但是仍然要注意使用this存在一定的风险。

 var myApp = {

     id: ,

     next: function() {
return this.id++;
}, reset: function() {
this.id = ;
}
}
window.console && console.log(
myApp.next(),
myApp.next(),
myApp.reset(),
myApp.next()
) //0, 1, undefined, 0

3. 模块模式

模块模式的好处是它将全局变量保存在了一个马上执行的函数包装器(a function wrapper)中,函数包装器将返回一个相当于模块公共接口的对象。同时,没有在函数包装器中return 的变量将是私有变量,只对引用它的公共函数可见。

 var myApp = (function() {

     var id= ;

     return {
next: function() {
return id++;
}, reset: function() {
id = ;
}
};
})(); window.console && console.log(
myApp.next(),
myApp.next(),
myApp.reset(),
myApp.next()
) //0, 1, undefined, 0

正如上面对象字面量方法一样,这里的命名空间名字可以很容易也很方便修改。但是对象字面量方法比较死板——它全是关于属性的定义,不能支持逻辑的书写,并且所有的属性必须被初始化且属性之间的值不能很简单的通过引用传递给另一个属性(所以,举例而言,内部闭包是不可能的)。模块模式相比而言没有上述限制,并且还拥有保护私有变量的特点。

动态命名空间

我们也可以叫做namespace injection. 命名空间被代理(proxy)表示,代理直接指向了函数包装器(the function wrapper)内部——这意味着我们不再需要绑定一个return给命名空间。这使得命名空间的定义更加灵活。动态命名空间有模块命名模式的所有好处,并且比模块模式更加直观和易于阅读。

4. 应用一个命名空间参数 Supply a Namespace Argument

这里我们简单的将命名空间作为一个变量传递给自己执行的函数。变量id是私有变脸,因为它没有定义给context变量。

 var myApp = {};
(function(context) {
var id = ; context.next = function() {
return id++;
}; context.reset = function() {
id = ;
}
})(myApp); window.console && console.log(
myApp.next(),
myApp.next(),
myApp.reset(),
myApp.next()
) //0, 1, undefined, 0

我们甚至可以将context设置成全局对象(只要改变一个单词就可以啦!)

 var myApp = {};
(function(context) {
var id = ; context.next = function() {
return id++;
}; context.reset = function() {
id = ;
}
})(this); window.console && console.log(
next(),
next(),
reset(),
next()
) //0, 1, undefined, 0

5. 使用this关键字作为命名空间代理(a Namespace Proxy)

使用this关键字作为命名空间的好处是,this关键字是在给予的执行环境中是静态的,它不会偶然改变。

 var myApp = {};
(function() {
var id = ; this.next = function() {
return id++;
}; this.reset = function() {
id = ;
}
}).apply(myApp); window.console && console.log(
myApp.next(),
myApp.next(),
myApp.reset(),
myApp.next()
); //0, 1, undefined, 0

因为apply和call函数是将this和指定的函数对象绑定,所以上述(function(){ ...... }).apply(命名空间),匿名函数里面的this一定指向命名空间。

下面解释了apply和call函数执行环境绑定的功能:

 var subsys1 = {}, subsys2 = {};
var nextIdMod = function(startId) {
var id = startId || ; this.next = function() {
return id++;
}; this.reset = function() {
id = ;
}
}; nextIdMod.call(subsys1);
nextIdMod.call(subsys2,); window.console && console.log(
subsys1.next(),
subsys1.next(),
subsys2.next(),
subsys1.reset(),
subsys2.next(),
subsys1.next()
) //0, 1, 1000, undefined, 1001, 0

当然,想和全局环境绑定,超级简单.....

 nextIdMod();   

 window.console && console.log(
next(),
next(),
reset(),
next()
) //0, 1, undefined, 0

使用apply和call的最大好处是可以随便使用任何你想绑定的环境对象。

 

其他考虑:

我没有使用内嵌的命名空间,因为它们很难跟踪,并且它们会将你的代码变得臃肿。对喜欢包装链(package chains )的怀旧Java码农而言,复杂的内嵌命名空间很符合他们的胃口。

js没有官方的命名空间的概念,所以你可以随心所欲大展身手创建自己的解决方案。

原文链接:https://javascriptweblog.wordpress.com/2010/12/07/namespacing-in-javascript/

js中的命名空间的更多相关文章

  1. js中创建命名空间的几种写法

    在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子: var sayHello = function() { return 'Hel ...

  2. 在js中创建命名空间的几种写法

    在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子:   var sayHello = function() { return 'H ...

  3. 关于js中namespace命名空间模式

    命名空间有助于减少程序中所需要的全局变量的数量,并且同时有助于避免命名冲突或过长的名字前缀. 关于命名空间的例子: /** * 创建全局对象MYAPP * @module MYAPP * @title ...

  4. JavaScript中创建命名空间

    引用:http://ourjs.com/detail/538d8d024929582e6200000c   在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺 ...

  5. 在JavaScript中创建命名空间的几种写法

    在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子: var sayHello = function() { return 'Hel ...

  6. JS中的自执行函数

    本来规划的是2013年,狠狠的将JS学习下,谁知计划赶不上变化,计划泡汤了.13年的我对JS来说可以说是属于跟风,对它的理解和认识也仅仅是皮毛而已,也是因为要完成<ArcGIS API for ...

  7. js中静态函数与变量

    一 私有变量和函数 js中没有概念上的私有,公有也没有静态和非静态相关概念,有的只能是通过作用于来模仿 函数的块级作用域使得函数内部成员可以不被外部所访问,比如我们使用块级作用于定义一个类 //定义一 ...

  8. js中的面向对象入门

    什么是对象 我们先来看高程三中是如何对对象进行定义的 "无序属性的集合,其属性可以包括基本值.对象或者函数",对象是一组没有特定顺序的的值.对象的没个属性或方法都有一个俄名字,每个 ...

  9. Day046--JavaScript-- DOM操作, js中的面向对象, 定时

    一. DOM的操作(创建,追加,删除) parentNode 获取父级标签 nextElementSibling 获取下一个兄弟节点 children 获取所有的子标签 <!DOCTYPEhtm ...

随机推荐

  1. Spring IOC知识java反射

    [1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http: ...

  2. 【java】深入分析Java ClassLoader原理

    一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程 ...

  3. 【报错】spring整合activeMQ,pom.xml文件缺架包,启动报错:Caused by: java.lang.ClassNotFoundException: org.apache.xbean.spring.context.v2.XBeanNamespaceHandler

    spring版本:4.3.13 ActiveMq版本:5.15 ======================================================== spring整合act ...

  4. [LeedCode OJ]#85 Maximal Rectangle

     [ 声明:版权全部,转载请标明出处.请勿用于商业用途. 联系信箱:libin493073668@sina.com] 题目链接:https://leetcode.com/problems/maxima ...

  5. css3 - 语言伪类选择器

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  6. C 标准库 - <time.h>

    C 标准库 - <time.h> 简介 time.h 头文件定义了四个变量类型.两个宏和各种操作日期和时间的函数. 库变量 下面是头文件 time.h 中定义的变量类型: 序号 变量 &a ...

  7. Android Design Support Library概览

    尊重劳动成果.转载请注明出处:http://blog.csdn.net/growth58/article/details/47972467 关注新浪微博:@于卫国 邮箱:yuweiguocn@gmai ...

  8. Git命令学习总结(-)

    入职的第一天,让git命令直接给难住了,汗!使用习惯可视化的工具对于命令行早就忘记的一干二净.还好,回家自己练习一下,总会没有错的.git就不做简介了,版本管理除了svn就是git了,其他的都无所谓了 ...

  9. angular input file 上传文件

    <body > <div ng-controller="fileCtrl"> <form ng-submit="submit(obj)&qu ...

  10. Python笔记——基本数据结构:列表、元组及字典

    转载请注明出处:http://blog.csdn.net/wklken/archive/2011/04/10/6312888.aspx Python基本数据结构:列表,元组及字典 一.列表 一组有序项 ...