Convert ES6 into ES5 with Babel
How ES6 features convert into ES5 by Babel.
spread/rest object({…{}})
1 | var _extend = Object.assign || |
//Caution: Why use Object.prototype.hasOwnProperty.call(source, key)
instead of source.hasOwnProperty(key)
Because Javascript does not protect the property name hasOwnProperty
; thus , if the possiility exists that an object might have a property with this name, it is nessary to use an external
hasOwnProperty
to get correct results.
Let’s see some example
1 | var foo = { |
what is difference between commonjs module & es module
模块化规范:即为JavaScript提供一种模块编写,模块依赖和模块运行的方案
AMD, CMD 运行时异步加载模块, webpack构建时模块合并分块
babel将还未被宿主环境直接支持的ES6 module编译为commonjs
ES6模块的设计思想是尽量的静态化
,使得编译时就能确定模块的依赖关系,以及输入和输出的变量
,
CommonJS模块就是对象,输入时必须查找对象属性。ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入
。
1 | // a.js |
- import is hoisted
- es module is imported by a specify path in AST. commonjs in runtime to know where module is .
- es module will export object reference. comonjs export the copy of object;
1 | // imports are hoisted |
the actual code transformed by babel
1 | // a.js |
严格模块主要有一下限制
- 变量必须声明后再使用
- 函数的参数不能有同名属性,否则报错
- 不能使用with语句
- 不能对只读属性赋值,否则报错
- 不能使用前缀
0
表示八进制数, 否则报错 - 不能删除不可删除的属性, 否则报错
- 不能删除变量
delete prop
,会报错,只能删除属性delete global[prop]
eval
不会在它的外层作用域引入变量eval
和arguments
不能被重新赋值arguments
不会自动反映函数参数的变化- 不能使用
arguments.callee
- 不能使用
arguments.caller
- 禁止this指向全局对象
- 不能使用
fn.caller
和fn.arguments
获取函数调用的堆栈 - 增加了保留字(比如
protected
,static
和interface
)
尤其注意,this
的限制。ES6模块中,顶层的this
指向undefined
,即不应该在顶层代码使用this
ES6模块,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应的关系
1 | export 1; |
ES6 export 语句输出的接口,与其对应的值时动态
绑定关系
import 语句会执行所加载的模块,因此可以有下面的写法
import "lodash"
CommonJS 模块的加载原理
require
命令第一次加载commonjs模块,就会执行整个模块,然后在内存生成一个对象
1 | { |
以后需要用到这个模块时,就会到这个内存对象的exports
上取值。
即使再次执行require命令,也不会再执行这个模块,而是到缓存之中取值。 也就是说,CommonJS模块无论加载多少次,都只会在第一次加载时运行一次
,就返回第一次运行的结果。除非手动清除系统缓存。