JS命名空间(namespace)
2014-08-26 17:52
337 查看
命名空间namespace(某些语言中叫package),是一个在静态语言中常见的概念。它可以帮助我们更好地整理代码,并可避免命名冲突。
举一个简单的例子,如果有两个人都叫小明,我们很难区分和引用这两个人。但如果我们在他们前面加上命名空间,比如:北京的小明和上海的小明,那么区分起来就容易的多了,也不会因为重名而找错人了。
遗憾的是,JS中并不提供原生的命名空间支持。在JS中创建的任何对象都默认是全局对象。在现代的大规模JS开发中,不采用命名空间会造成非常糟糕的命名方式,比如用前缀命名函数和变量,导致代码丑陋不可读。当引入第三方库后,更可能会发生命名覆盖的情况。
那么JS中该如何解决这个问题呢?你可以等ES6的到来,到那时我们就有native命名空间可用了。当下我们还需要一些特殊手段来模拟命名空间的概念。
简单地说,我们可以创建一个简单对象字面量来打包所有的相关函数和变量。这个简单对象字面量模拟了命名空间的作用。
person对象被完整包含到MYNAMESPACE这个命名空间中了,使用方法也很简单:
如此一来,通过命名空间我们就可以声明多个person对象了。
看起来这个模拟的命名空间不错,但这里还是有一个问题。我们这里使用的是一个全局对象,在添加这个“命名空间”的时候,我们有可能覆盖全局空间中的同名对象。因此我们需要在声明命名空间前进行检查,保证全局空间的安全:
若全局空间中已有同名对象,则不覆盖该对象;否则创建一个新的命名空间。采用了这个安全的命名空间后,声明的方法也需要略作改动:
注意在定义命名空间构造函数时,需要将其定义在prototype上,否则新建的实例无法访问对象的方法。
举一个简单的例子,如果有两个人都叫小明,我们很难区分和引用这两个人。但如果我们在他们前面加上命名空间,比如:北京的小明和上海的小明,那么区分起来就容易的多了,也不会因为重名而找错人了。
遗憾的是,JS中并不提供原生的命名空间支持。在JS中创建的任何对象都默认是全局对象。在现代的大规模JS开发中,不采用命名空间会造成非常糟糕的命名方式,比如用前缀命名函数和变量,导致代码丑陋不可读。当引入第三方库后,更可能会发生命名覆盖的情况。
那么JS中该如何解决这个问题呢?你可以等ES6的到来,到那时我们就有native命名空间可用了。当下我们还需要一些特殊手段来模拟命名空间的概念。
简单地说,我们可以创建一个简单对象字面量来打包所有的相关函数和变量。这个简单对象字面量模拟了命名空间的作用。
var MYNAMESPACE = { person: function(name) { this.name = name; this.getName = function() { return this.name; } } };
person对象被完整包含到MYNAMESPACE这个命名空间中了,使用方法也很简单:
var p = new MYNAMESPACE.person("ifcode"); p.getName(); // ifcode
如此一来,通过命名空间我们就可以声明多个person对象了。
嵌套命名空间
我们也可以用是嵌套命名空间,更详细的归类对象:var MYNAMESPACE = { PEOPLE: { person: function(name) { this.name = name; this.getName = function() { return this.name; } } }, PET: { dog: function(petName) { this.petName = petName; this.getPetName = function() { return this.petName; } } } };
看起来这个模拟的命名空间不错,但这里还是有一个问题。我们这里使用的是一个全局对象,在添加这个“命名空间”的时候,我们有可能覆盖全局空间中的同名对象。因此我们需要在声明命名空间前进行检查,保证全局空间的安全:
var MYNAMESPACE = MYNAMESPACE || {};
若全局空间中已有同名对象,则不覆盖该对象;否则创建一个新的命名空间。采用了这个安全的命名空间后,声明的方法也需要略作改动:
var MYNAMESPACE = MYNAMESPACE || {}; MYNAMESPACE.person = function(name) { this.name = name; }; MYNAMESPACE.person.prototype.getName = function() { return this.name; }; // 使用方法 var p = new MYNAMESPACE.person("ifcode"); p.getName(); // ifcode
注意在定义命名空间构造函数时,需要将其定义在prototype上,否则新建的实例无法访问对象的方法。
小结
采用命名空间后,代码结构会更加清晰可读。若不想每次都手动构建命名空间,也可以采用类似requirejs这样的module pattern库来整理代码结构。相关文章推荐
- JS--命名空间的理解(namespace)
- JS--命名空间的理解(namespace)
- js命名空间的函数namespace
- JS中命名空间(namespace)的概念和使用
- JS命名空间(namespace)
- JS--命名空间的理解(namespace)
- JavaScript 实现命名空间(namespace)的最佳方案——兼容主流的定义类(class)的方法,兼容所有浏览器,支持用JSDuck生成文档
- 模块(Module)的用途1 命名空间(Namespace)
- [转]Java的类装载器(Class Loader)和命名空间(NameSpace)
- Ext源码分析:解析Ext的命名空间,Ext.namespace
- C#.NET中命名空间的运用(关键字namespace)
- Namespace:命名空间
- 命名空间 namespace
- [摘自c#Bible]c#中namespace的使用(命名空间)
- [Flex]Flex SDK 4(Gumbo)命名空间(NameSpace)概述
- 命名空间std,using namespace std
- Java的类装载器(Class Loader)和命名空间(NameSpace)
- JavaScript创建命名空间(namespace)的最简实现
- Java的类装载器(Class Loader)和命名空间(NameSpace)
- Namespace(命名空间)的使用