为您解惑:JS模块与命名空间的介绍........
2016-10-31 18:08
459 查看
起因
将代码组织到类中的一个重要原因是让代码更加“模块化”,可以在很多不同的场景中实现代码的重用。但类不是唯一的模块化代码的方式。
一般来讲,模块是一个独立的JS文件。模块文件可以包含一个类定义、一组相关类、一个实用函数库或者一些待执行的代码。
模块化的目标是支持大规模的程序开发,处理分散源中代码的组装,并且能让代码正确运行,哪怕包含了不需要的模块代码,也可以正确执行代码。
理想状态下,所有模块都不应当定义超过一个全局标识。
模块函数
通过把模块定义在某个函数的内部来实现,定义的变量和函数都属于该函数的局部变量,在函数外不可见。实际上,可以将这个函数作用域用做模块的命名空间(模块函数)
一旦将模块代码封装进一个函数中,就需要一些方法导出公用API,以便在模块函数外部调用它们。
下面有几种方式导出公用API:
首先创建一个命名空间
2. 返回命名空间对象
如果模块API包括多个单元,则它可以返回命名空间对象
<span style="font-size:14px;">// 为school添加students模块
school.students = (function() {
// 这里定义了很多类如课程类/成绩类, 使用局部变量和函数
function Subject() { /* ... */ }
function Grade() { /* ... */ }
// 通过返回命名空间对象将API导出
return {
Subject: Subject,
Grade: Grade
};
})();
</span>3. 通过关键字new调用
另外一种类似类似技术:把模块函数当做构造函数,通过new来调用。把它们(公共API)赋值给this属性来将其导出
<span style="font-size:14px;">school.students = (new function() {
// ..... 这里省略了代码 ......
// 将API导到this对象中
this.Subject = Subject;
this.Grade = Grade;
// 注意,这里没有返回值
}()); // 括号写在里面。这里是创建新实例,new后面应紧跟构造函数的调用而不是表达式</span>4. 已定义命名空间对象
作为一种替代方案,如果已经定义了全局命名空间对象,通过模块函数可以直接设置那个对象的属性。
<span style="font-size:14px;">// 如果已经定义了命名空间对象
var school; // 创建school命名空间
if(!school) school = {};
school.students = {}; // student命名空间已经定义
(function(students) {
// ..... 这里省略了代码 ......
// 将公共API导到上面定义的命名空间中
students.Subject = Subject;
students.Grade = Grade;
// 这里也不需要返回值
})(school.students);</span>
为此,导出公共API的方式已经讲完。
将代码组织到类中的一个重要原因是让代码更加“模块化”,可以在很多不同的场景中实现代码的重用。但类不是唯一的模块化代码的方式。
一般来讲,模块是一个独立的JS文件。模块文件可以包含一个类定义、一组相关类、一个实用函数库或者一些待执行的代码。
模块化的目标是支持大规模的程序开发,处理分散源中代码的组装,并且能让代码正确运行,哪怕包含了不需要的模块代码,也可以正确执行代码。
理想状态下,所有模块都不应当定义超过一个全局标识。
模块函数
通过把模块定义在某个函数的内部来实现,定义的变量和函数都属于该函数的局部变量,在函数外不可见。实际上,可以将这个函数作用域用做模块的命名空间(模块函数)
一旦将模块代码封装进一个函数中,就需要一些方法导出公用API,以便在模块函数外部调用它们。
下面有几种方式导出公用API:
首先创建一个命名空间
<span style="font-size:14px;">// 创建一个全局变量用来存放与学校相关的模块 var school; // 创建school命名空间 if(!school) school = {};</span>1. 利用构造函数
<span style="font-size:14px;">/ 返回Student构造函数来导出公共API school.Student = (function() { function Student() { } // ...... 定义Student的原型对象和私有属性和方法 ........ return Student; // 返回Student构造方法导出公共API })(); </span>
2. 返回命名空间对象
如果模块API包括多个单元,则它可以返回命名空间对象
<span style="font-size:14px;">// 为school添加students模块
school.students = (function() {
// 这里定义了很多类如课程类/成绩类, 使用局部变量和函数
function Subject() { /* ... */ }
function Grade() { /* ... */ }
// 通过返回命名空间对象将API导出
return {
Subject: Subject,
Grade: Grade
};
})();
</span>3. 通过关键字new调用
另外一种类似类似技术:把模块函数当做构造函数,通过new来调用。把它们(公共API)赋值给this属性来将其导出
<span style="font-size:14px;">school.students = (new function() {
// ..... 这里省略了代码 ......
// 将API导到this对象中
this.Subject = Subject;
this.Grade = Grade;
// 注意,这里没有返回值
}()); // 括号写在里面。这里是创建新实例,new后面应紧跟构造函数的调用而不是表达式</span>4. 已定义命名空间对象
作为一种替代方案,如果已经定义了全局命名空间对象,通过模块函数可以直接设置那个对象的属性。
<span style="font-size:14px;">// 如果已经定义了命名空间对象
var school; // 创建school命名空间
if(!school) school = {};
school.students = {}; // student命名空间已经定义
(function(students) {
// ..... 这里省略了代码 ......
// 将公共API导到上面定义的命名空间中
students.Subject = Subject;
students.Grade = Grade;
// 这里也不需要返回值
})(school.students);</span>
为此,导出公共API的方式已经讲完。
相关文章推荐
- JS模块与命名空间的介绍
- JS模块与命名空间的介绍
- JS框架设计之命名空间设计一种子模块
- js模块,类,继承,命名空间,私有属性等相关概念梳理
- js模块,类,继承,命名空间,私有属性等相关概念梳理
- JS模块与命名空间
- 为您解惑:JavaScript命名空间的理解与实现........
- SPORE,一个很好的实现JS命名空间的管理,模块的定义,与自动加载依赖模块的脚本文件
- 第一课:js命名空间的介绍,js对象的扩展以及js数组化
- PetShop 4.0 设计研究——petShop 4.0 的命名空间 以及各个项目模块的说明
- PetShop 的命名空间 以及各个项目模块的说明
- 多个 JS 文件共享一个命名空间
- F#入门-第二章 F#基础-第二十二节 模块与命名空间
- 有关js命名空间管理文件同步载入[转]
- 转载:ASP.NET中命名空间的简单介绍
- JavaScript重构(一):模块划分和命名空间
- ASP.NET中的命名空间的简单介绍
- js实现命名空间(ajax封装类)
- [开发故事],第十五回,在Js中应用命名空间
- PetShop 4.0 设计研究——petShop 4.0 的命名空间 以及各个项目模块的说明