JavaScript import&export

支撑 ES6 模块的两个主要关键字是 import 和 export 。它们在语法上有着自己的特点,这篇文章主要介绍这些特点。

首先值得注意的一点就是这两个关键字都必须在最顶层作用域使用。也就是说,它们必须出现在所有代码块和函数的外面。

一. 导出成员

export 关键字可以放在声明前面,或者作为一个操作符与要导出的列表绑定。例:

//放在声明前面
export function foo(){ //... };
export var a = [1,2,3];

// 与导出列表绑定
function b(){ // ... };
var c = [1,2,3];
var d = 'd';
export { b,c,d };

以上都称为命名导出,因为导出的变量和函数与名称绑定。

注意点:

  1. 没有用 export 标识的模块作用域内的内容都是私有的。
  2. 这里说的顶层作用域是模块本身的作用域,不是全局。模块虽然还能够访问“全局”作用域,但是“全局”作用域不作为词法上的顶层作用域。

---------------------------分割线-------------------------------

function item(){ .. }
export { item as newItem };

var year = 2019;
export { year };

// 导出 year 之后再对它进行操作
year = 2020; 

上面这个例子:

  1. 如果导入 item ,只有 newItem 可以导入,item 是隐藏在模块内部的。
  2. 导出 year 之后再对它赋值,year 的值是 2020。

产生这种现象的本质是绑定(export 导出变量)指向变量本身的引用或者指针,而不是这个值的复制。

引用的情况是针对导出简单数据类型来说的,导出指向的不是那个值,而是那个值的引用;指针这个概念JavaScript中并没有,说这个的意思是,导出复杂数据类型的时候,导出指向的是指向堆的地址,不是堆里面的内容。

默认导出的细节,例:

function foo(){...}
export default foo;

function boo(){...}
export {boo as default};

注意点:

扫描二维码关注公众号,回复: 8645795 查看本文章
  1. export default foo 导出的是函数表达式绑定,也就是说相当于 export default function foo(…),如果之后给 foo 赋予一个不同的值,从此模块导入 foo 的话,仍然是原来的函数,不是新的值。
  2. 而 boo 导出,绑定到的是 boo 标识符而不是它的值,与之前说的绑定是一样的。

所以,如果你默认导出的值需要更新,采用 export {boo as default};如果不需要更新,采用谁都可以。

二. 导入成员

如果想导入一个模块 api 的某个特定的命名成员到顶层作用域,可以使用以下语法:

import { foo, boo } from 'file';

{ foo, boo } 这个语法看起来像是对象字面量和对象解构的语法。但实际上不是,它就是专用于模块的一种形式而已。

列出的标识符 foo,boo 必须和模块 api 的命名导出匹配。且它们会在当前作用域绑定为顶层标识符。

可以对导入绑定标识符重命名,例:

	import {foo as redFoo } from 'file';
	redFoo();

如果是只有一个默认导出,可以省略 {…} 语法,例:

function foo(){...}
export default foo;

import foo from 'file';
// 或者
import { default as foo} from 'file'; 

以上都是单独导入的,如果想要把一个模块的api全部导入到一个命名空间,有一种方式,也称为命名空间导入。

export function foo(){...}
export var x = 42;
export function boo(){...}

import * as container from 'file';
container.foo();
container.x; 		// 42 

上面的例子中,导出全部被绑定到 container 这个命名空间。


还有一点,import 导入是提升的。例:

foo();
import foo from 'file';

foo()可以正常执行,说明 foo 被提升到了顶层作用域最上面。

import 'file'

上面这个例子,一般来说没什么作用,它相当于加载了一遍‘file’模块(如果它还没有加载过)。这可以用来执行一些有副作用的模块。

发布了45 篇原创文章 · 获赞 3 · 访问量 606

猜你喜欢

转载自blog.csdn.net/qq_40653782/article/details/104004953