排名前10的ES6特性之模块【Modules】

Ranking(2)  Modules

本章节讲述在ES6中如何构建Modules

 

1、开始。

在ECMAScript 6中,modules 是存储在文件中,一般而言是一个文件一个模块。
有两种方式将模块中的方法暴露给外部使用

1.1 Multiple named exports

//多个暴露的方法或者属性

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

说明:
const 声明创建一个只读的常量。这不意味着常量指向的值不可变,而是变量标识符的值只能赋值一次;
详询:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const
let声明了一个块级域的本地变量,并且可以同时初始化该变量;
let 允许把变量的作用域限制在块级域中。
与 var 不同处是:var 申明变量要么是全局的,要么是函数级的,而无法是块级的。
详细参考请 详询:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let

//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

你也可以引入整个模块:

//------ main.js ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

1.2 Single default export

有如下两种方式

//------ myFunc.js ------
export default function () { ··· } // 

//------ main1.js ------
import myFunc from 'myFunc';
myFunc();

或是定义一个类 class:

//------ MyClass.js ------
export default class { ··· } //

//------ main2.js ------
import MyClass from 'MyClass';
let inst = new MyClass();

1.3 Browsers: scripts versus modules

                          Scripts             Modules
HTML element   <script>     <script type="module">

 

2 Modules in JavaScript

2.1 ECMAScript 5 module systems

代表有AMD CMD 方式,这里就不再细说。
对于COMMOM js 上述例子的表现形式如下:

    //------ lib.js ------
    var sqrt = Math.sqrt;
    function square(x) {
        return x * x;
    }
    function diag(x, y) {
        return sqrt(square(x) + square(y));
    }
    module.exports = {
        sqrt: sqrt,
        square: square,
        diag: diag,
    };

    //------ main.js ------
    var square = require('lib').square;
    var diag = require('lib').diag;
    console.log(square(11)); // 121
    console.log(diag(4, 3)); // 5

2.2 ECMAScript 6 module systems

ES6 模块加载兼容CMD AMD 的优势。
另外,ES6 模块语法比commonJS 更加严格
基于 promise的module loader,接收单个模块模型

System.import('some_module')
    .then(some_module => {
        // Use some_module
    })
    .catch(error => {
        ···
    });

也可以接收多个模块,使用 Promise.all() 

Promise.all(
        ['module1', 'module2', 'module3']
        .map(x => System.import(x)))
    .then(([module1, module2, module3]) => {
        // Use module1, module2, module3
    });

2.3 More loader methods

ES6 loader 拥有更多的load 方法,其中最为重要的是以下3个 System.module(source, options?)
//evaluates the JavaScript code in source to a module (which is delivered asynchronously via a Promise).
System.set(name, module)
//is for registering a module (e.g. one you have created via System.module()).
System.define(name, source, options?)
//both evaluates the module code in source and registers the result.

2.4 细节讲述

讲述 CommonJS vs ES6:

In CommonJS, imports 只是export的备份.
In ES6, imports 是只读read-only 类型.
下面通过demo说明

 

2.4.1 IN COMMONJS

//------ lib.js ------
var counter = 3;
function incCounter() {
    counter++;
}
module.exports = {
    counter: counter, // (A)
    incCounter: incCounter,
};

//------ main1.js ------
var counter = require('./lib').counter; // (B)
var incCounter = require('./lib').incCounter;

// The imported value is a (disconnected) copy of a copy
console.log(counter); // 3
incCounter();//
console.log(counter); // 3

// The imported value can be changed
counter++;
console.log(counter); // 4

另外一种表现形式也无法改变

//------ main2.js ------
var lib = require('./lib');

// The imported value is a (disconnected) copy
console.log(lib.counter); // 3
lib.incCounter();
console.log(lib.counter); // 3

// The imported value can be changed
lib.counter++;
console.log(lib.counter); // 4

 

2.4.2  In ES6

//------ lib.js ------
export let counter = 3;
export function incCounter() {
    counter++;
}


//------ main1.js ------
import { counter, incCounter } from './lib';

// The imported value `counter` is live
console.log(counter); // 3
incCounter();
console.log(counter); // 4

// The imported value can’t be changed
counter++; // TypeError
If you import the module object via the asterisk (*), you get the same results:

//------ main2.js ------
import * as lib from './lib';

// The imported value `counter` is live
console.log(lib.counter); // 3
lib.incCounter();
console.log(lib.counter); // 4

// The imported value can’t be changed
lib.counter++; // TypeError

 

再来看一例子 ,你不能改变imports ,但是可以改变它的属性方法

//------ lib.js ------
export let obj = {};

//------ main.js ------
import { obj } from './lib';

obj.prop = 123; // OK
obj = {}; // TypeError


下一节 讨论 Destructuring.

 

posted @ 2016-01-06 16:55  xiaozhanglang  阅读(1017)  评论(0编辑  收藏  举报