精选文章 es6 import和export 用法及实战

es6 import和export 用法及实战

作者:qq_21761149 时间: 2020-07-27 10:37:57
qq_21761149 2020-07-27 10:37:57

欢迎大家访问我的博客 www.kevink.club


看到vue 不断的进行模块的引用, 并且每个模块都会有export, 不禁想去尝试一下。 

说实话,之前用js写功能类也没这么用过, 今天就来实现以下

###尝试一:

index.html

```



   
    Title



```

已运行就报错了, ```Uncaught SyntaxError: Cannot use import statement outside a module```

去查一下, 
```TML 网页中,浏览器通过 script 标签加载 JavaScript 脚本。由于浏览器脚本的默认语言是 JavaScript,因此type="application/javascript"可以省略。在报错中了解到,是说无法在模块外部使用import语句,因为Module 的加载实现的是es6语法,所以在浏览器加载html文件时,需要在script 标签中加入type="module"属性。```

好了,咱们再去试试
###尝试二:

index.html

```



   
    Title



```

exportFile.js 内容
```
const name = 'cx'
function say(name) {
    return 'hello ' + name
}
function dodo() {
    return 'do '+ 'something'
}
export {name, say}

```

![2020-07-27T14:13:15.png][1]


实现了我想要输出的结果.

###总结
我在exportFile.js 定义了一个常量```name```,还有一个方法 ```say()```, export暴露了出来, 在index.html中```import```引用暴露出来的```name``` 常量和 ```say()```方法. ```dodo()```方法我没并没有暴露出来,所有在index.html文件中是无法进行引入```import```引入,如果引入,则会报错:```Uncaught SyntaxError: The requested module './exportFile' does not provide an export named 'dodo'```

我们用来干什么? 
* 像是 php 语言中的私有方法和公有方法,公有方法就需要export暴露出来, 私有方法不要暴露出来。
* 像是 Go 语言中结构体的私有方法和共有方法, 公有方法方法名的第一个字母大写,当获得结构体的对象时,可以使用共有的方法;私有方法第一个字母小写,不能通过实例化的对象使用该方法。

----

###0、前言
前端工程,在最早的时候是没有模块的概念的。随着前端工程的发展,前端开发也越来越规范化,更像是软件工程了。那么随之而来的,为了解决工程化的问题,就引入了模块的概念。但是在早期,因为ecmascript原本是没有模块语法的,所以采用的都是社区的各种版本协议,其中影响最深的,就是nodejs使用的CommonJS规范 。

当模块化的概念越来越重要的时候,在es6中,引入了模块的语法:import ,下面我们简单了解一下,import是怎么使用的。一下内容,参考 官方文档

###1、export
一个js文件,可以理解成一个模块,这个模块可以被任意其他的模块引入,引入的结果,就是对这个模块进行执行后,所持有的对象。那么随之而来就有一个问题,文件模块被引入后,所有的东西,都是在自己的作用域中,主动发起引入行为的那个文件,虽然获取到了被引入的对象,但是并不能访问作用域里的东西,所以提供了export,来决定一个模块对外暴露什么东西。

export的作用,就是用于从模块中导出函数、对象或原始值,以便其他程序可以通过 import 语句使用它们.

在import 一个文件的时候,会获取这个文件对象,默认是空对象,代表我们不能访问文件的东西。使用export,来给这个对象添加内容

用法:
module1.js :
```
function f1 (){
    console.log("module - 1 : functino 1")
}

let b = {
    name:"test_obj"
}

let str = "hell绿绿绿"

export {
    f1,b,str
}
```
在main.js 中进行引入

// 先忽略 import 的写法,后面再说明
```
import * as m1 from "./m1.js"
console.log(m1)
```
在这个文件中,我们对外暴露了 一个函数,一个变量,一个对象。所以,在使用 import 导入的文件对象,就不在是一个空对象,而是包含了export 内容的对象,所以,我们打印出m1.js 文件对象,也就是 m1 :
export导出的对象
所以,我们知道,export 导出的内容,都会添加到文件对象中,可以简单的先理解为深拷贝。

###2、export default
很多初学者很困惑,既然有了 export ,为什么还要有个 export default 呢?网上给出的答案往往是,作为文件的默认导出接口。那什么又是文件的默认导出接口呢?

其实这个问题很简单,我们先抛开 import ,不考虑import 的语法,仅考虑 export default具体做了什么。
修改 module1.js :
```
function f1 (){
    console.log("module - 1 : functino 1")
}
let b = {
    name:"test_obj"
}
let str = "hell绿绿绿"
export {
    f1,b,str
}
export default{
    name:"default"
}
```
main.js不变,在执行一遍,继续查看打印出来的文件对象:
export-default
发现了吗,export default 的作用,是给文件对象,添加一个 default属性,default属性的值也是一个对象,且和export default导出的内容完全一致。

###3、文件导出的总结
那么到这里,我们明白了,一个js文件被当做一个模块引入,会暴露为一个对象(也就是被导入后,可以当做一个对象来操作)。

export的作用,是在这个文件对象中添加属性,export出来的东西,全部会添加到文件对象中。

export default 的作用,是给文件对象的 default 属性,添加值。

###4、import
在上面的例子中,我们明白了模块对外暴露的都是什么东西,那么我们如何来使用文件对外暴露的东西呢?
首先我们已经明白,文件对象是什么。

###4.1导出整个文件对象
那么首先,我们就导出整个文件对象,看一看是什么样子的。就是上面例子中,我们使用到的语法,import * 来导出文件模块的所有接口,as m_name 来指定一个命名空间对象。
main.js :
```
import * as m1 from "./m1.js"
console.log(m1)
```
示例中的m1 命名空间对象,可以访问到文件对象的所有对外接口,包括export,和export default。
export-default

###4.2 导出export的部分接口
在实际开发中,我们并不需要导出所有的接口。例如在vue项目中,使用某个组件库中的某个组件,我们只需要引入这一个组件,不必要引入所有组件。

我们知道,import 导出的是整个文件对象,那么我们直接在 import 语句中,对这个对象进行解构,就可以获得其中某一部分接口:
main.js :
```
import {f1,b} from "./m1.js"
console.log(f1)
console.log(b)
```
打印结果,就是:
在这里插入图片描述
但是这种方式,仅限于获取文件对象的正常属性,default属性是获取不到的,原因有两个:

未解构的对象全部进行了丢弃
default是关键字,不能再解构中当做变量进行使用
###4.3 导入export default 的接口
export default是文件的默认导入,其实这句话的重点,并不在于 export default,而是在于 import 语句是如何处理文件默认导入的。
修改main.js 文件内容为:
```
import d from "./m1.js"
console.log(d)
```
打印出来,惊奇的发现,d 竟然和 export default 的内容一样。

所以,现在可以这么理解,所谓的默认导入,就是毫无花哨的直接导入一个模块,然后赋值给一个命名空间,这种时候,这个命名空间,持有的就是 文件对象的default 对象,也就是export default 出来的东西。

其实,默认导入可以理解为也是解构的一个语法糖(仅仅用作理解,实际是语法错误的):

import d from "./m1.js"  可以等价为 import {default as d} from "./m1.js"
###5、import动态导入
还有一种高端的玩法,在项目中也是很有用处的。

import不光是一个关键字,同时也是一个函数,函数的参数是需要导入模块的路径,函数返回一个promise对象。
```
import("./m1.js").then(m=>{
  console.log('then:',m)
})
```
在这段代码中,then中回调的m,就是文件模块的整个文件对象(包括export和export default)。

###6、import不导入文件对象
import还可以不导入文件对象,仅仅是使用文件模块提供的功能。也就是传说中的,import将文件模块仅仅最为副作用进行导入,而不获取文件模块的接口。

在项目中,实践的地方,例如一个vue项目,我们需要给vue对象挂载很多东西,但是全部写在src/main.js 文件中,又会显得特别啰嗦,不利于维护,也没能体现工程化的理念。所以我们常常单独新建一个文件lib/init.js ,然后在这个 init.js 文件中,编写相关逻辑。这个文件的作用,仅仅是执行一遍,我们不期望这个文件暴露什么变量,所以没必要获取文件对象。那么这个时候,import 关键字的另一个作用就体现出来了:
main.js :
```
import './lib/init.js';
```
使用import直接引用一个文件时,会执行一遍这个文件,而不获取任何文件对象。

  [1]: http://www.kevink.club/usr/uploads/2020/07/87190316.png

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:利用pyinstaller+nssm将python程序打包为exe并封装为系统服务,实现开机自启/后台运行

下一篇:Redis6之pub/sub发布与订阅(对比List和Kafka)

您可能感兴趣

  • Java项目 (SpringBoot+SpringCloud) 十次方:前端(一) 前端环境搭建

    1 需求分析与技术架构 一.理解前后端分离开发 前后端分离已成为互联网项目开发的业界标准使用方式,通过nginx+tomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器,车载终端,安卓,IOS等等)打下坚实的基础。 以前老的方式是: 1.产品经理/领导/客户提出需求 2.UI做出...

  • 3分钟掌握ES6、7 编程风格

    块级作用域 (1)let 取代 var ES6提出了两个新的声明变量的命令:let和const。其中,let完全可以取代var,因为两者语义相同,而且let没有副作用。 'use strict'; if (true) { let x = 'hello'; } for (let i = 0; i < 10; i++) { console.log(i); } 上面代码如果用var替代...

  • TypeScript基础以及在Vue中的应用

    更多写作与参考学习材料等可登录ZG文库网http://www.zgwenku.com/ TypeScript推出已经很长时间了,在Angular项目中开发比较普遍,随着Vue 3.0的即将推出,TypeScript在Vue项目中使用也即将成为很大的趋势,笔者也是最近才开始研究如何在Vue项目中使用TypeScript进行项目的开发。 准备 阅读博客前希望读者能够掌握如下技能,文章中也会相对应...

  • 前端模块化:AMD和CMD,后端模块化:commonJS,ES6模块化

    如果你对模块化已经了解,可以直接从第三点开始阅读。 一、模块化的概念: 在进行项目分析或者编码时,先把项目进行拆分,拆分成很多的类,对象,很多的函数等等。能够提高代码的复用性。这些被拆分出来的类型,对象,函数就是模块。就像一辆汽车是由很多的零部件组成,每个零部件就是一个小模块,而由很多零件组成的发动机之于一辆汽车可以认为是一个大模块;或者说,一台计算机,由主板,cpu,内存,硬盘,显示器,键...

  • js几种模块化CommonJS、AMD、CMD,ES6模块化整理

    本文是基于 https://blog.csdn.net/howgod/article/details/87466148 该链接,自己整理巩固记忆的一篇文章,原文解释描写十分的详细贴切易懂。 一、CommonJS 概述:Node应用模块组成,每个文件就是一个模块,服务器端模块加载运行时同步的,浏览器端模块需要提前编译打包处理。 特点:1.所有代码都运行在模块作用域,不污染全局 2.模块可以多次...

  • JS 进阶系列问题

    本文截取自来自Lydia Hallie 小姐姐的 javascript-questions,从基础到进阶,测试你有多了解 JavaScript,刷新你的知识,或者帮助你的 coding 面试! 答案在问题下方。祝你好运! 1. 输出是什么? function sayHi() {   console.log(name)   console.log(age)   var name = 'Lydi...

  • javaScript--ECMAScript 6

    ECMAScript 6 一、ECMAScript 6 简介 1、ECMAScript 和 JavaScript 的关系 一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系? 要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成...

  • 基于react-app搭建react-router+redux项目

    前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应用的过程。 代码地址:React全家桶实现一个简易备忘录 原文博客地址:React全家桶实现一个简易备忘录 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damo...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。