模块的写法

javascript不是一种模块化编程语言,不支持其他编程语言中的类(class)、模块(module)。ES6中将会支持,但是宿主环境不一定支持。

但是在现有的环境中,js也可以模拟“类”和“模块”的效果。

一:初始写法

模块是实现一定功能的方法,把几个不同的函数放在一起,就是一个模块。

在一个html页面中引入两个js文件,

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="module.js"></script>
    <script src="use.js"></script>
</head>
<body>

</body>
</html>

module.js:定义模块

var currentYear = new Date().getFullYear();
var age = function(birthdayYear){
    "use strict";
    return currentYear - birthdayYear;
}

use.js:使用模块

var _age = age(1987);
console.log("年龄:"+_age);
currentYear = 2014;
console.log("修改年龄:"+age(1987));

结果输出:

年龄:29
修改年龄:27

优点:定义和使用方便,简单明了

缺点:使用了全局变量,容易与其它变量名冲突,模块之间的关系较弱。

二:对象写法

module.js:定义模块

var module = new Object({
    currentYear:new Date().getFullYear(),
    age:function(birthdayYear){
        "use strict";
        return this.currentYear - birthdayYear;
    }
});

或者

var module = {
    currentYear:new Date().getFullYear(),
    age:function(birthdayYear){
        "use strict";
        return this.currentYear - birthdayYear;
    }
};

use.js:使用模块

var age = module.age(1987);
console.log("年龄:"+age);
module.currentYear = 2015;
console.log("修改年龄:"+module.age(1987));

结果输出:

年龄:29
修改年龄:28

优点:方法名不会与其他模块的方法名冲突,使用的时候,module.method()

缺点:对象名会与其他模块的对象命冲突,模块成员暴露,内部变量可以被修改。

三:立即执行函数

module.js:定义模块

var module = (function(){
    "use strict";
    var currentYear = new Date().getFullYear();
    var age = function(birthdayYear){
        "use strict";
        return currentYear - birthdayYear;
    };
    return {
        age:age
    };
})();

use.js:使用模块

var age = module.age(1987);
console.log("年龄:"+age);
console.log("module.currentYear:"+module.currentYear);

结果输出:

年龄:29
module.currentYear:undefined

优点:内部成员不会被暴露,内部变量不能被修改

四:模块的拆分与继承

module.js:定义模块,module模块含有age方法用来计算年龄

var module = (function(){
    "use strict";
    var currentYear = new Date().getFullYear();
    var age = function(birthdayYear){
        "use strict";
        return currentYear - birthdayYear;
    };
    return {
        age:age
    };
})();

module1.js:定义模块,module1模块定义了新方法birthdayYear,用来计算出生年,且把该模块添加在module模块上,

var module = (function(mod){
    "use strict";
    var currentYear = new Date().getFullYear();
    mod.birthdayYear = function(age){
        "use strict";
        return currentYear - age;
    };
    return mod;
})(module);

use.js:使用模块

var age = module.age(1987);
console.log("今年"+age+"岁了");
var birthdayYear = module.birthdayYear(29);
console.log("出生于"+birthdayYear+"年");

结果输出:

今年29岁了
出生于1987年

优点:在立即执行函数的前提下,把复杂模块拆分开

五:模块的拆分与继承做兼容性处理

为了兼容,防止module模块还未加载,module1已经加载,这时候会报错,

html以如下方式引入:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="module1.js"></script>
    <script src="module.js"></script>
    <script src="use.js"></script>
</head>
<body>

</body>
</html>

module.js

var module = (function(){
    "use strict";
    var currentYear = new Date().getFullYear();
    var age = function(birthdayYear){
        "use strict";
        return currentYear - birthdayYear;
    };
    return {
        age:age
    };
})();

module1.js

写法1

var module = (function(mod){
    "use strict";
    var currentYear = new Date().getFullYear();
    mod.birthdayYear = function(age){
        "use strict";
        return currentYear - age;
    };
    return mod;
})(module);

写法2:

var module = (function(mod){
    "use strict";
    var currentYear = new Date().getFullYear();
    mod.birthdayYear = function(age){
        "use strict";
        return currentYear - age;
    };
    return mod;
})(window.module);

以上两种写法报错:module1.js:4 Uncaught TypeError: Cannot set property 'birthdayYear' of undefined

写法3:不会报错,参数可以传一个空对象

var module = (function(mod){
    "use strict";
    var currentYear = new Date().getFullYear();
    mod.birthdayYear = function(age){
        "use strict";
        return currentYear - age;
    };
    return mod;
})(window.module || {});

results matching ""

    No results matching ""