Module的语法

---恢复内容开始---

1.概述

  ES6中模块的设计思想:尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入输出的变量。

  

import {stat,exists,readFile} from 'fs';

2.严格模式

  --

    变量必须声明后再使用

    函数的参数不能有同名属性

    不能使用with语句

    不能对只读属性赋值

    不能使用前缀0表示八进制数

    不能删除不可删除的属性

    不能删除变量dalete prop,只能删除属性delete global[prop]

    eval不会在它的外层作用域引入变量

    eval和arguments不能被重新赋值

    arguments不会自动反映函数参数的变化

    不能使用argument.callee

    不能使用argument.caller

    禁止this指向全局对象

    不能使用fn.caller和fn.arguments获取函数调用的堆栈

    增加了保留字(如protected、static和interface)

   

  ES6中顶层的this指向undefined,因此不应该在顶层代码使用this

3.export命令

  必须使用export关键字输出模块内部的变量后,外部才能读取

  

//profile.js
   
 export var firstName = 'Micheal';
 export var lastName = 'jackson';
 export var year = 1958;

  另一种写法

  

//profile.js
 var firstName = 'michael';
 var lastName  = 'jackson';
 var year = 1958;
 export {firstName,lastName,year};

   在export命令后面使用大括号指定所要输出的一组变量。可以一眼看出输出了那些函数或类

  

  export除了输出变量还可以输出函数或类

  

export function multiply(x,y){
   return x * y;  
};

  export输出的变量就是本来的名字,但是可以使用as重命名

  

function v1(){ ... }
function v2(){ ... }

export{
   v1 as streamV1,
   v2 as streamV2,
   v2 as streamLatestVersion  
}

  重命名后,V2可以用不同的名字输出两次

  注意:export命令规定的是对外的接口,必须与模块内部的变量建立一一对应的关系

  如果输出的不是接口而是一个值得话会报错

  

//写法1
export var m = 1;

//写法2
var m = 1;
export {m};

//写法3
var n = 1;
export {n as m};

 

  上面三种写法都是正确的,规定了对外的接口m。其他脚本可以通过这个接口,取到值1。它们的实质是,在接口名与模块内部变量之间,建立了一一对应的关系。

  function和calss的输出,也必须遵循这样的写法

  

//错误
function f(){}
export f;


//正取
export function f(){};

//正确
 function f(){}
 export {f};

 要么export 后面直接跟函数,要么export后面使用{函数名}

 export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口可以取到模块内部实时的值

export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);

 CommonJs模块输出的是值得缓存,不存在动态更新。

  export命令可以处于模块任何位置,只要处于模块顶层就可以。不能放在块作用域中

放在块作用域中就没法做静态优化,违背ES6模块设计初衷。

  

function foo(){
 export default 'bar' //SyntaxError
}
foo()

  

 import命令

  import命令用于加载模块。大括号里的变量名必须与被导入模块对外接口一致

  重命名:使用as关键字重命名

import {lastName as surname} from './profile';

  如果只是模块名,不带有路径,那么必须有配置文件,告诉js引擎该模块的位置

  

import {myMethod} from 'util';

  不带路径必须要有配置文件

  

  import命令具有提升效果,会提升到整个模块的头部首先执行

  

foo();
import { foo } from 'my_module';

  提升的本质:import命令是编译阶段执行的,在代码运行之前。

  由于import是静态执行,所以不能使用表达式和变量

  

//报错
import {'f' + 'oo'} from 'my_module';

//报错
 let module = 'my_module';
 import { foo } from module;

//报错
 if( x === 1){
   import { foo } from 'module1';
   import { foo } from 'module2';  
}

在静态分析阶段,表达式都是无法得到值的。

  import会执行所加载的模块

  

import 'loadsh';

  以上仅仅执行loadsh模块,但是不输入任何值

  多次重复同一import语句,那也只会执行一次,不会执行多次

  

import { foo } from 'my_module';
import { bar } from 'my_module';

//等同于

import { foo, bar} from 'my_module';

  import语句是Singleton(单实例)模式

  CommonJS模块的require命令和import命令最好别写在同一模块中,因为import会首先执行

  模块的整体加载

    用( * )指定一个对象,所有的输出值都加载在这个对象上

import * as circle from './circle';

 

 

   模块整体加载所在的那个对象,不允许运行时改变。

  

import  * as circle from './circle';

//下面两行代码不允许

circle.foo = 'hello'
circle.area = function (){}

 

  export default命令

    export default为模块指定默认输出

  

//export-default.js

export default function(){
  console.log('foo');
}

  其它模块加载export default命令导出的模块时,import命令可以为该匿名函数指定任意名字

  

//import-default.js

import customName from './export-deault';
customName(); //'foo'

  

  注意:这时import命令后面不使用大括号

  export default命令也可以用在非匿名函数前

  

export default function foo(){
  console.log('foo');   
}

//另一种写法

function foo(){
 console.log('foo');
}
export default foo;

  上面代码中,foo函数的函数名foo,在模块外部是无效的。加载的时候,视同匿名函数加载

  本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。

  

export default命令后面不能跟变量声明语句

  

  

 

---恢复内容结束---

posted @ 2017-08-16 13:48  小小滴白  阅读(456)  评论(0编辑  收藏  举报