js中的命名空间
尽量不要使用全局变量,防止环境污染和命名冲突。
所以,将全局变量放在一个命名空间下,是一个好的解决方案。
静态命名空间
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中的命名空间的更多相关文章
- js中创建命名空间的几种写法
在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子: var sayHello = function() { return 'Hel ...
- 在js中创建命名空间的几种写法
在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子: var sayHello = function() { return 'H ...
- 关于js中namespace命名空间模式
命名空间有助于减少程序中所需要的全局变量的数量,并且同时有助于避免命名冲突或过长的名字前缀. 关于命名空间的例子: /** * 创建全局对象MYAPP * @module MYAPP * @title ...
- JavaScript中创建命名空间
引用:http://ourjs.com/detail/538d8d024929582e6200000c 在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺 ...
- 在JavaScript中创建命名空间的几种写法
在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子: var sayHello = function() { return 'Hel ...
- JS中的自执行函数
本来规划的是2013年,狠狠的将JS学习下,谁知计划赶不上变化,计划泡汤了.13年的我对JS来说可以说是属于跟风,对它的理解和认识也仅仅是皮毛而已,也是因为要完成<ArcGIS API for ...
- js中静态函数与变量
一 私有变量和函数 js中没有概念上的私有,公有也没有静态和非静态相关概念,有的只能是通过作用于来模仿 函数的块级作用域使得函数内部成员可以不被外部所访问,比如我们使用块级作用于定义一个类 //定义一 ...
- js中的面向对象入门
什么是对象 我们先来看高程三中是如何对对象进行定义的 "无序属性的集合,其属性可以包括基本值.对象或者函数",对象是一组没有特定顺序的的值.对象的没个属性或方法都有一个俄名字,每个 ...
- Day046--JavaScript-- DOM操作, js中的面向对象, 定时
一. DOM的操作(创建,追加,删除) parentNode 获取父级标签 nextElementSibling 获取下一个兄弟节点 children 获取所有的子标签 <!DOCTYPEhtm ...
随机推荐
- linux mysql添加用户名并实现远程访问
第一步:登陆linux,在终端登陆mysql #mysql -u root -p 第二步:查询系统用户列表并进行添加用户 mysql>select host,user,password from ...
- ArcGIS 安装中,SQL的使用出现错误的解决
1. SQL Server Configuration Manager 中 SQL Server Services出现 “远程调用失败..” 的问题 解决方法是卸载
- 跳转到指定页面popToViewController用法
有人问popToViewController的用法 就写了下了 希望能帮到有需要的人 [self.navigationController popToViewController:[self.navi ...
- cygwin搭建ssh服务器
下载cygwin的setup.exe安装包
- Mingw/Code::Block/wxWidgets 搭建
Mingw The MinGW project maintains and distributes a number of different core components and suppleme ...
- 搭建windows下的odoo开发环境
odoo运行环境的必须要要求是 python环境 postgreSQL数据 数据库可以安装在别的机器上,比如服务器:当然对于开发环境,通常,数据库与代码调试安装在同一台机器上. 首先安装 postgr ...
- shell脚本编写-自动部署及监控
1.编写脚本自动部署反向代理.web.nfs: I.部署nginx反向代理两个web服务,调度算法使用加权轮询 II.所有web服务使用共享存储nfs,保证所有web都对其有读写权限,保证数据一致性: ...
- 利用反射快速给Model实体赋值 使用 Task 简化异步编程 Guid ToString 格式知多少?(GUID 格式) Parallel Programming-实现并行操作的流水线(生产者、消费者) c# 无损高质量压缩图片代码 8种主要排序算法的C#实现 (一) 8种主要排序算法的C#实现 (二)
试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有120多个字段.现在合同每一次变更时都需要对合同原始信息进行归档一次,版本号依次递增.那么我们就要新建一张合同历史表, ...
- DataTable和DataRow利用反射直接转换为Model对象的扩展方法类
DataTable和DataRow利用反射直接转换为Model对象的扩展方法类 /// <summary> /// 类 说 明:给DataTable和DataRow扩展方法,直接转换为 ...
- Can't open named pipe to host: . pipe: MySQL
今天遇到mysql连接odbc时报例如以下错误:Can't open named pipe to host: . pipe: MySQL 错误截图例如以下: 依照网上说的方法包含mysql的官方说法都 ...