只是搬迁本身以前丢在简书的文字写于初学es6时因此语句不通(虽然并没有价值)git
是只是export,因此......import忽略es6
本篇代码运行环境为
{"presets": [ "es2015","stage-2" ] }
这只是做为参考,且只是运行环境,不推荐在学习ES6时将代码所有转译为ES5,ES6转化后的代码只能告诉你结果,相比较而言,缘由或是理由的价值超过结果,学习ES6,不仅仅要知道代码运行的结果,最重要的目的是,知其因此然,了解一个行为为何会这么发生,行为的背后又是什么,这才是学习者所须要追寻的github
文章参考: You-Dont-Know-JS ECMAScript 6 入门 ES6规范15.2.3.2 Static Semantics: BoundNamesbash
首先登场的就是 export , 这是一个主要关键词,基本用法是放置在一个"声明"以前,或一组由{}
语法(注意,此处的{}语法与对象无关)
包裹的即将被导出的"标识符"以前app
//export 放置在"声明"以前
export var a = 1, b = 2, c = 3
export let a = 1
export const a = 1
export let { a } = { a: 1 }
export var foo = function() {}
export function foo() {}
//export 放置在一组"标识符"以前
var a = 1, b = 2
export { a, b }
//等同于
export var a = 1
export var b = 2
复制代码
以上例子有一个明确的共同点,export 后面没有出现“表达式”。实际上,单独的export 是对变量标识符(指针位置)的绑定,并期许未来会把对应的标识符(指针)导出。函数
将“变量标识符”导出,这样的描述容易产生混淆,考虑下面的代码学习
var a = 1
export { a }
a = 3
//等同于
export var a = 1
a = 3
复制代码
当这个模块被导出后,若是赋值发生,那么已被导出的值也将被更新,不管导出发生在任何阶段。进一步的说,在被导入时的值是可有可无的。这些绑定是实时的连接,因此惟一重要的是当你访问这个绑定时它当前的值是什么。ui
参考规范15.2.3.2
ExportDeclaration : export VariableStatement
1. Return the BoundNames of VariableStatement.
ExportDeclaration : export Declaration
1. Return the BoundNames of Declaration.
能够看到export 的导出是明确的
复制代码
另外“标识符”一词引用于The above rule means that each ReferencedBindings of ExportClause is treated as an IdentifierReference.主要是词穷,而且由于模块导出与赋值是不一样的,在进行导出时,实质上是导出了一个单向绑定的
(不容许在导入的一方进行改变)
变量的引用,是的,更准确的说应该是对于变量这个容器的引用,模块导出并不关心变量的值。spa
在进行导出的时候,可使用别名,关键词 as指针
var a = 1
export { a as b }
//将 a 重命名为 b
复制代码
"在一个模块中,使用import命令的时候,用户须要知道所要加载的变量名或函数名,不然没法加载。可是,用户确定但愿快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。"
"为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。"
上述两句直接摘自ECMAScript 6 入门,主要是感受是很恰当的描述,若是加以变更反倒多此一举了,固然还不够全面,因此对default进来如下的补充
每一个模块定义只能有一个default,它是惟一的,每一个被导出的模块只包含一个default元素,因此export default命令在模块内只被容许使用一次。
本质上export default就是输出一个叫作default的默认标识符。等同于,将export default 以后的内容以赋值的形式添加到default元素上。
var a = 1
export default a
//等同于
export default 1
//导出的是那表达式在那一刻的值的绑定,不是 标识符a的绑定(export.default = 表达式)
复制代码
export default 有许多微妙的细节,使人困扰的(不是结果,而是行为)。请思考下面的代码。
//m2.js
1.
function foo() {}
export default foo
foo = 'change'
2.
export default (function foo() {})
foo = 'change'
3.
function foo() {}
export { foo as default }
foo = 'change'
//因为上文已经描述过,default接近于标识符,因此,能够直接重命名foo做为default导出。
4.
export default function foo() {}
foo = 'change'
//另外一模块
import * as all from 'm2.js'
console.log(all)
复制代码
你的大脑可以清晰的知道每一个模块即将会发生的事情吗?若是不能那么请继续阅读,若是能,那么也但愿你继续阅读,重温复习这一片断。下面让我复制代码,描述并解释每一模块的行为。 ######模块1.
function foo() {}
//声明foo
export default foo
//将foo赋值给default元素(注意,此时foo是表达式)
foo = 'change'
//结果
{ default: [Function: foo] }
复制代码
export default 导出的是那一个函数表达式在那一刻的值的绑定,不是 标识符foo的绑定。换句话说,export default ..接收一个表达式。若是你稍后在你的模块内部赋给foo一个不一样的值,这个模块导入将依然表示本来被导出的函数,而不是那个新的值。
规范里定义了export default 表达式的导出相关行为export default AssignmentExpression
ExportDeclaration : export default AssignmentExpression ; 1.Return «"default"». 简单解释下,就是将表达式的值赋予default,而后返回default ######模块2.
export default (function foo() {})
将(..)赋值给default 元素(注意,()是表达式)
foo = 'change'
//结果
ReferenceError: foo is not defined
export default !function foo() {}
!等运算符能够包装一个函数使它做为一个表达式返回值
复制代码
export default (function foo(){}),export default后面的是函数表达式,并非函数声明定义,因此它对应的规范与模块1相同,导出的ExportedBindings也就是一个«"default"»。
这里之因此报错是由于函数表达式只会返回函数自己做为值,并不会在外部做用域定义同名变量,因此下面的foo = 'change'找不到foo这个定义。
######模块3.
function foo() {}
export { foo as default }
foo = 'change'
//结果
{ default: 'change' }
复制代码
ExportDeclaration : export Declaration 1.Return the BoundNames of Declaration. 行为与 export '标识符‘相同,因此引用的规范相同,惟一须要理解的是default是能够被赋值
######模块4.
export default function foo() {}
//一个函数声明出现了!
foo = 'change'
//结果
{ default: 'change' }
复制代码
function foo..部分是一个函数表达式,可是对于模块内部做用域来讲,它被视为一个函数声明,由于名称foo被绑定在模块的顶层做用域
export default 函数声明定义在规范中定义的行为,对应的是export default HoistableDeclaration. ExportDeclaration : export default HoistableDeclaration 1.Let declarationNames be the BoundNames of HoistableDeclaration. 2.If declarationNames does not include the element "default", append "default" to declarationNames. 3.Return declarationNames.
能够看到按照规范若是将要导出的声明没有包含元素default,那么就进行赋值(规范概念),最后返回的是一个当前绑定的标识符,与前面的表达式时状态不一样。因此结果可以看到,导出值被更新了。
原标题为ES6 Module 详解,而后发现本身并无真正理解Module这部分因而停笔,回去看书了,实际意义上本文是为了总结知识
初学ES6,文章有误请指点,文内部分用词不许确也请谅解,虽然引用了规范,可是并无能力进行解读,惭愧。
文章参考: You-Dont-Know-JS ECMAScript 6 入门 ES6规范15.2.3.2 Static Semantics: BoundNames