JavaScript的导入导出

时间:2025-01-21 08:39:38

1、概述

①、特点:

  • ES6新增的特性,类似于java中import

  • 有两个关键字:export-》导出,import-》导入

  • 区分更明细,可以只导出一个变量、对象或者函数,而java只能引入整个类

②、和java比较

  1. js中没有Java里用来定义成员的访问权限的public、private等修饰符,所以用export做部分变量导出,二者孰优孰劣见仁见智

  2. js模块引入的优点

    • 导入即可用,无需再去关注原生文件其它属性、方法、对象、变量、函数的访问权限

2、使用方式汇总

1、export 基本导入

使用说明
  • 在变量、函数声明处添加export关键字

  • 要导出的变量或函数必须有修饰符

    • export var a = 1; (√)

    • export a; (错)

    • 函数同理,需function修饰

    • 原因见《2.3 export default特点》第一项

  • 不可以直接导出常量

  • import {要导入的对象集合} from '文件路径';

  • 注意:被导入的变量、函数必须用大括号包裹,否则报错

  • 可选择导入,支持导入部分变量、函数

代码示例

export var a =1;
export let b = 2;
export const c = 3;
export var d;
d = 4;
let name = 'showMyName';
export function showMyName(){
    ('我是一个要被导出的函数-->'+name);
}

import {a,b,c,d,showMyName} from './';
(a);
(b);
(c);
(d);
showMyName();
输出结果:
1
2
3
4
我是一个要被导出的函数-->showMyName

2、export Default 模块化

使用说明
  • 使用export defualt导出

  • 相比于export每次只能导出一个变量或函数,export可以导出一个集合,也就是所谓的module

  • import时不需要加上大括号,并且可自定义导入模块的名字

    • 也就是说,import a from '' 等同于 import b from '';

    • 自定义模块名,使得代码的可读性更高,但也会导致规范化问题,可能本人看着顺眼,另一个人就不喜欢了

  • 可以直接导出常量

代码示例

var a =1;
var b =2;
function logA(){
    ('a的值为--->'+a);
}
export default {a,logA};

import impModule from './';
();
(());
执行结果:
1
a的值为--->1

特点--自动将模块包装成对象导出
①、直接导出常量

原因分析(不一定对,以后再分析):

  • 导入模块时,相当于导入了一个对象!

  • 那么自定义的模块名,就成为了模块对象的变量名

  • 对象就灵活起来了,可以有name/age/getName()等属性或方法,也可以本身就代表一个常量值

  • 所以defaultModule就相当于一个简单number类型对象,值是99

  • 所以可以看到一个现象

    • export defualt 99; (√)

    • export defualt {99,88}; (×) 这种写法在js看来不是想导出两个常量,而是你要导出一个Object对象,没有属性、方法那必 然报错

    • export defualt [99,88]; (√) 将两个常量包装成一个数组对象即可

  • 代码示例

;

export default 99;

;

import defaultModule from './';
(defaultModule);
​
执行结果:
99
②、导出多个变量
var a =1;
var b =2;
function logA(){
    ('a的值为--->'+a);
}
export default {a,logA};
import impModule from './';
(impModule);
执行结果:
{a:1,logA: [Function: logA] }

明显看到导入的module内容被自动包括成了一个对象

3、组合导出

使用说明
  • 在一个js中,只可以有一个export default

  • 但是,可以有0或多个export

  • 特性和前面两种方式一样,只不是是组合使用,方便了

代码示例
export var a = 1;
let b = 2;
function logB() {
    (b);
}
export default {b,logB};
import {a} from './';
import impDefault from './';
(a);
();
()
执行结果:
1
2
2

3、常见问题

①、export、import会导致变量提升吗?

答:

  • import、export可能只需要用代码执行顺序来形容更合适

  • export不会出现变量提升的现象,甚至会在最后执行,能不能变量提升主要是看 变量本身的定义修饰符(var、let、const、function)

//错误写法1:
a = 1;
export let a;
​
//正确写法1
a = 1;
export var a;
​
//正确写法2
export let a;
a = 1;

原因分析(猜测):

//错误写法1在js解释器中的样子
a = 1;
let a;
export a;//伪代码,关注顺序即可,这种写法本身是错误的
​
//正确写法1在js解释器中的样子
var a;
a = 1;
export a;
​
//正确写法2在js解释器中的样子
let a;
a = 1;
export a;

现象:export语句总在所有代码之后执行

  • import会出现类似变量提升的现象,原因是import语句会被解释器提升到所有代码之前执行

//下列两种写法均可执行
import {a} from './';
(a);
或者:
(a);
import {a} from './';
结果:
1

现象:import语句总在所有代码之前执行

和java的区别:java的import语句显式写在文件的最上方,js允许import写在任何地方,但看起来结果都是import语句总在所有代码之前执行

②、export default也会在代码在代码最下面执行吗?

答:

  • 和export不同,export default不会在代码最下方执行

  • 它就在代码所在行导出模块对象

  • 先导出后定义,分两种情况,会不会报错全看变量本身的修饰符有没有变量提升的现象

export default a;
var a = 1;
//导出的实际是个{undefined},就是代码执行顺序
//解释器中如下
var a;
export default a;
a = 1;
export default a;
let a = 1;
//直接报错  ReferenceError: Cannot access 'a' before initialization(初始化之前不能访问a,因为这会儿a还没被定义)

③、导入模块后修改了变量值,会导致原模块中的值改变吗?

答:

不清楚原理,只通过现象总结一下,以后明白了再补充:

  • import的简单类型不可直接修改,原因不清楚,不知道js是咋处理的

    export function logA() {
        (a);
    }
    export let a = 1;
    import {a,logA} from './';
    (a);
    a = 2;
    (a);
    logA()
    /*
    代码执行到 a=2 时会直接报错!!
    TypeError: Assignment to constant variable.
    就好像a成了一个被const修饰的变量一样
    */
  • 引用类型修改会影响原来值

export function logA() {
    (a);
}
export let a = {name:'张三'};
import {a,logA} from './';
(a);
 = "李四";
(a);
logA()
//执行结果
{ name: '张三' }
{ name: '李四' }
{ name: '李四' }

④、export如何导出常量

答:

  • 无法直接导出常量 export a; 直接报错

  • 曲线救国 export {a}; 就可以了

  • export default 可能就是把这个过程给隐式的执行了一下,谁知道呢