学习笔记《ES6 的模块加载》

一些资料

阮一峰的《ECMAScript 6 入门》中,有对模块机制的详细介绍:
http://es6.ruanyifeng.com/#docs/module

Babel 官方的《Learn ES2015》则相对比较简略:
https://babeljs.io/learn-es2015/#ecmascript-2015-features-modules

http://es6-features.org/ 官方的介绍很简洁:
http://es6-features.org/#ValueExportImport

严格加载模式

ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict"; 严格模式主要有以下限制:

  • 变量必须声明后再使用
  • 函数的参数不能有同名属性,否则报错
  • 不能使用with语句
  • 不能对只读属性赋值,否则报错
  • 不能使用前缀0表示八进制数,否则报错
  • 不能删除不可删除的属性,否则报错
  • 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
  • eval不会在它的外层作用域引入变量
  • eval和arguments不能被重新赋值
  • arguments不会自动反映函数参数的变化
  • 不能使用arguments.callee
  • 不能使用arguments.caller
  • 禁止this指向全局对象
  • 不能使用fn.caller和fn.arguments获取函数调用的堆栈
  • 增加了保留字(比如protected、static和interface)

export default 命令

下面两行代码的差别是,前者针对的是一个 export default 的输出,而后者则是一个 export someName 这样的输出,在使用 import 的时候,后者需要使用「{}」符号,前者不需要:

// 第一组
export default function () { // 输出
  // ...
}

import crc32 from './crc32'; // 输入

// 第二组
export function crc32() { // 输出
  // ...
};

import {crc32} from './crc32'; // 输入

如果想在一条import语句中,同时输入默认方法和其他变量,可以写成下面这样:

import lodash, { each } from 'lodash';

export 与 import 的复合写法

export { foo, bar } from 'my_module';

// 等同于
import { foo, bar } from 'my_module';
export { foo, bar };

// 整体输出
export * from 'my_module';

// 整体输出默认接口
export { default } from 'foo';

require()

require() is not part of your standard JavaScript. In context to your question and tags, require() is built into Node.js to load modules. The concept is similar to C/Java/Python/[insert more languages here] imports or includes.

浏览器上的不同加载方式



defer与async的区别是:前者要等到整个页面正常渲染结束,才会执行;后者一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

浏览器加载 ES6 模块,也使用

上面代码在网页中插入一个模块foo.js,由于type属性设为module,所以浏览器知道这是一个 ES6 模块。

浏览器对于带有type="module"的

script 标签的async属性也可以打开,这时只要加载完成,渲染引擎就会中断渲染立即执行。执行完成后,再恢复渲染。


ES6 模块也允许内嵌在网页中,语法行为与加载外部脚本完全一致。


对于外部的模块脚本(上例是foo.js),有几点需要注意。

  • 代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。
  • 模块脚本自动采用严格模式,不管有没有声明use strict。
  • 模块之中,可以使用import命令加载其他模块(.js后缀不可省略,需要提供绝对 URL 或相对 URL),也可以使用export命令输出对外接口。
  • 模块之中,顶层的this关键字返回undefined,而不是指向window。也就是说,在模块顶层使用this关键字,是无意义的。
  • 同一个模块如果加载多次,将只执行一次。

你可能感兴趣的:(学习笔记《ES6 的模块加载》)