import命令

179 阅读1分钟

题目:写出下面代码输出的结果,并做解释

// counter.js
let counter = 10;
let add = () => {
    console.log(counter);
}
export { counter, add };

// index.js
add();
import { counter, add } from './counter.js';
counter += 1;
console.log(counter);

答案: 10 报错

解析

  • 引入模块是只读的,不能修改。并且import具有提升效果。
  • 题目中加载了变量count,对其进行重新赋值会报错,因为count只是一个只读的接口

知识点

  • import命令输入的变量是只读的
  • import命令具有提升效果,会提升至整个模块的头部,首先执行
  • import是静态执行,不能使用表达式和变量
  • importSingleton模式

1. import命令输入的变量是只读的

  • import本质上是输出接口,即不允许在加载模块的脚本里面改写接口
import { a } from './xxx.js';
a = {}; // Syntax Error: 'a' is read-only
  • a是一个只读接口。但如果a是一个对象,改写a的属性是允许的
// counter.js
let counter = {};
export default counter;

// index.js
import myCounter from './counter.js';
myCounter.hello = 'helloCounter';

myCounter属性可以改写成功,其他模块也可以读到改写后的值,但是这种写法很难查错,建议当作完全只读。

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

  • import命令是编译阶段执行的,在代码执行之前

3. import是静态执行,不能使用表达式和变量

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

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

4. importSingleton模式

  • 多次重复执行同一句import语句,只会执行一次
import { foo } from 'my_module';
import { bar } from 'my_module';

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

虽然foobar在两个语句加载,但是他们对应的是同一个my_module实例。