通用的命名空间函数
2.创建通用的命名空间函数
===================
**知识点**
1.为什么要检测空间和空间成员是否已创建?
2.创建通用的命名空间成员的创建方法
-------------------------------------------------
1.为什么要检测空间和空间成员是否已创建?
--------------------------------
为了防止空间或空间已有成员,被新建成员所覆盖,所以创建之前必须检测
-------------------------------------------------
2.创建通用的命名空间成员的创建方法
----------------------------
- 自动解析要创建的空间成员名称
- 自动创建空间成员
-------------------------------------------------
### 示例代码: code/demo02.html
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>通用的命名空间函数</title>
</head>
<body>
<script>
// 之前方法创建的命名空间
var APP = {}; // 非常不安全,很有可能被同名变量覆盖
// 更好的创建方式: 如果没创建APP空间变量,则创建它
// 如果已创建,则会忽略以下的代码
if (typeof APP === 'undefined') {
var APP = {};
}
// 或者, 设置APP 默认值
var APP = APP || {};
// 其实以上代码,在空间成员较长,层级不深的情况下,还能接受,
// 一旦成员很多,或者层级很深,就会产生大量的冗余代码,例如
// APP.module1.module2.module3, 对于这三个模块,
// 将不得不做三次验证以确保不会重复生成产生覆盖
// 所有,非常有必要创建一个: 通过的命名空间方法,来简化这种验证判断操作
var APP = APP || {};
APP.namespace = function (ns_string) {
// 分离出要创建的成员的各个部分,返回一个字符串数组
var parts = ns_string.split('.'); // 各部分之间是用"."分隔的
var root = APP; // 设置根空间名称,这也是最终的返回值
// 因为根空间是固定的,不需要进行循环遍历,所以要从空间成员数组中删除根空间
if (parts[0] === 'APP') {
parts = parts.slice(1); // 返回从第二个元素开始的全部剩余元素,并覆盖原数组
}
// 循环遍历需要添加的空间成员各个组成部分
for (var i = 0; i < parts.length; i += 1) {
// 如果当前空间不存在这个成员,则创建它
if (typeof root[parts[i]] === 'undefined') {
root[parts[i]] = {}; // 新属性为一个对象字面量
}
// 如果已经存在该属性了,则用root记录当前属性,实现递归
root = root[parts[i]];
}
// 返回生成的成员属性
return root;
};
var module = APP.namespace('APP.module.controller.action');
console.log(module === APP.module.controller.action);
console.log(module); // 的确是生成该属性, 值一个空对象字面量
// 可单步调试, 最后查看window中的APP对象的内容,可以看到明显的层级关系
</script>
</body>
</html>
```