赞
踩
我们对于可以导入模块依赖到自己的代码中的需求随着大量JavaScript框架的涌现也越来越多。
JS中有无数地方使用了这些框架,或者你已经早就对它们很熟悉了,就像MooTools,jquery,甚至common.js和require.js。
直到最近,最早执行模块是靠可以自我执行的匿名函数,也就是所谓的立即执行函数(Immediately-Invoked Function Expression, IIFE )。
我有点偏题了,那么,可以自我执行的匿名函数是怎样运行的呢?它类似于下面这样:
//Module Starts
(function(window){
var sum = function(x , y){如果你对上面的不陌生,你也不会对jquery也使用这样的模块感到惊讶。如果上面的看上去陌生,请多看几次。
你或许会对以下代码感到奇怪:
(function(window){
})(window);
那么,以上代码被用来干什么呢?它们被设计用来分割作用域以及避免函数和变量与其它代码混合。
这里有一些JS的库和环境做得更好,允许你把模块放进上面的文件,当我们需要什么JS模块,就调用什么模块。
比如:
新建一个math.js,在里面写上:
var sum = function (x, y) {
return x + y;
}
var sub = function (x, y) {
return x - y;
}
var math = {
findSum: function (a, b) {
return sum(a, b);
},
findSub: function (a, b) {
return sub(a, b);
}
};
exports.math = math;
再在同目录下的另一个js中写入:
var math = require("./math").math;
console.log(math.findSum(1, 2)); //3
console.log(math.findSub(1, 2)); //-1
在上面的2个js文件中,第二个js可以通过require.函数导入math.js并运行它。如果你懂一点Node.js,那么你也应该熟悉这种语法。这种设计被称为模块异定义(Asynchronous Module Definition, AMD),允许我们使用这些库的规范称为commonJS,同样它也适用于大多数Node应用。它比立即执行函数更简单和直观,但不幸的是,大多数情况下它(CommonJS)只适用于服务器端,。
当然,现在有很多解决办法使我们在浏览器端使用AMD规范,但是它们还是不够完美。幸好ES6出现了,它允许我们像在AMD里面简单而自然(inherently and simply)得使用模块。
这里有一个很简单的例子--我们有一个模块,名为math,一个属性名为pi,一个方法名为sum。那我们怎么创建一个模块呢?我们先创建一个叫lib的文件夹,里面创建一个叫math的文件。math代码如下:
export class Math {
constructor() {
this.sum = function(x, y){
return x + y;
}
this.pi = 3.141593;
}
findSum(a, b) {
return this.sum(a, b);
}
getPi() {
return this.pi;
}
}
如果你思路跟上了,你会发现这个类的语法看上去非常自然。如果你想知道我到底想表达什么,那就开始看看这个类吧。
我们可以看到,这个类暴露了两个方法。另一个关键组件是export。这个export就是我们要暴露的。那么它的实现呢?对于项目中的每个文件,我们只需要执行对应的import指令。记住,我们保存的math.js,导入之后,要在变量中创建类的实例,就是这样!
import {Math} from 'lib/math';console.log(math.getPi()); //3.141593
上面的代码到底怎么回事?不要慌,最关键的点是我们要把两个东西用在import里面:可以用于导入的类的名字(这里指Math),和它的文件所在路径(lib/math)。做完这些以后,我们可以声明它的实例,并且使用它而不会有任何差错。
再来一个例子如何?我们设置可以不用class,请注意观察我声明的文件:
//File: directory/name.js
export var environment = 'develop';
export var userName = 'Moshe';
export function sum(x,y) { return x + y;};
//Other file
import * as names from "directory/name";
console.log(names.environment); //develop
console.log(names.userName); //Moshe
console.log(names.sum(2,3)); //5
棒极了!我们可以导入任何我们暴露的对象。注意我们可以使用这个:
import {environment, userName, sum} as names from "directory/name";
也可以使用 "*"去获取所有对象。我们在一个变量内部进行的导入,现在我们执行的所有导出都可以被使用而且不必担心问题和作用域。现在谁还敢说这个不好或者不简洁么?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。