export default 和 export 区别

export default 和 export 区别

1.export与export default均可用于导出常量、函数、文件、模块等

2.你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其进行使用

3.在一个文件或模块中,export、import可以有多个,export default仅有一个

4.通过export方式导出,在导入时要加{ },export default则不需要

1.export
//a.js
export const str = “blablabla~”;
export function log(sth) {
return sth;
}
对应的导入方式:

//b.js
import { str, log } from ‘a’; //也可以分开写两次,导入的时候带花括号

2.export default
//a.js
const str = “blablabla~”;
export default str;
对应的导入方式:

//b.js
import str from ‘a’; //导入的时候没有花括号
使用export default命令,为模块指定默认输出,这样就不需要知道所要加载模块的变量名
//a.js
let sex = “boy”;
export default sex(sex不能加大括号)
//原本直接export sex外部是无法识别的,加上default就可以了.但是一个文件内最多只能有一个export default。
其实此处相当于为sex变量值"boy"起了一个系统默认的变量名default,自然default只能有一个值,所以一个文件内不能有多个export default。
// b.js
本质上,a.js文件的export default输出一个叫做default的变量,然后系统允许你为它取任意名字。所以可以为import的模块起任何变量名,且不需要用大括号包含
import any from “./a.js”
import any12 from “./a.js”
console.log(any,any12) // boy,boy

作者:开车去环游世界
链接:https://www.jianshu.com/p/edaf43e9384f
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
模块基础知识
每一个ES6模块都是一个包含JS代码的文件,模块本质上就是一段脚本,而不是用module关键字定义一个模块,但是模块与脚本还是有两点区别:

在ES6模块中,无论你是否加入“use strict;”语句,默认情况下模块都是在严格模式下运行。
在模块中你可以使用import和export关键字。
我们先来讨论export。默认情况下,你在模块中的所有声明相对于模块而言都是寄存在本地的。如果你希望公开在模块中声明的内容,并让其它模块加以使用,你一定要导出这些功能。想要导出模块的功能有很多方法,其中最简单的方式是添加export关键字。

// kittydar.js - 找到一幅图像中所有猫的位置
// (事实上是Heather Arthur写的这个库)
// (但是她没有使用ES6中新的模块特性,因为那时候是2013年)
export function detectCats(canvas, options) {
  var kittydar = new Kittydar(options);
  return kittydar.detectCats(canvas);
}
export class Kittydar {
  ... 处理图片的几种方法 ...
}
// 这个helper函数没有被export。
function resizeCanvas() {
  ...
}
...

你可以导出所有的最外层函数、类以及var、let或const声明的变量。

了解这些,你就可以编写一个简单的模块。你不需要将所有代码都放在一个IIFE或回调中,你只需要在模块中解放手脚,声明你需要的所有内容。代码就是模块,不是一段脚本,所以所有的声明都被限定在模块的作用域中,对所有脚本和模块全局不可见。你需要做的是将组成模块公共API的声明全部导出。

在模块中,除export之外的代码无异于普通代码,你可以访问类似Object和Array这样的全局对象。如果你在web浏览器中运行模块,你甚至可以使用document对象和XMLHttpRequest对象。

在一个独立文件中,我们可以导入detectCats()函数然后用它来做点儿什么:

// demo.js - Kittydar的demo程序
import {detectCats} from "kittydar.js";
function go() {
    var canvas = document.getElementById("catpix");
    var cats = detectCats(canvas);
    drawRectangles(canvas, cats);
}

如果想从一个模块中导入多个名称,你可以这样写:

import {detectCats, Kittydar} from "kittydar.js";

当你运行的模块中包含一条import声明时,首先会加载被导入的模块;然后依赖图的深度优先遍历按顺序执行每一个模块的主体代码;为了避免形成回环,所有已执行的模块都会被忽略。

这些就是模块的基本知识了,相当简单吧。😉

Export列表
你不需要标记每一个被导出的特性,你只需要在花括号中按照列表的格式写下你想导出的所有名称:

export {detectCats, Kittydar};
// 此处不需要 `export`关键字
function detectCats(canvas, options) { ... }
class Kittydar { ... }

export列表可以在模块文件最外层作用域的每一处声明,不一定非要把它放在模块文件的首行。你也可以声明多个export列表,甚至通过其它的export声明打造一个混合的export列表,只要保证每一个被导出的名称是唯一的即可。

重命名import和export
恰恰有时候,导出的名称会与你需要使用的其它名称产生冲突,ES6为你提供了重命名的方法解决这个问题,当你在导入名称时可以这样做:

// suburbia.js
// 这两个模块都会导出以`flip`命名的东西。
// 要同时导入两者,我们至少要将其中一个的名称改掉。
import {flip as flipOmelet} from "eggs.js";
import {flip as flipHouse} from "real-estate.js";
...

同样,当你在导出的时候也可以重命名。你可能会想用两个不同的名称导出相同的值,这样的情况偶尔也会遇到:

// unlicensed_nuclear_accelerator.js - 无DRM(数字版权管理)的媒体流
// (这不是一个真实存在的库,但是或许它应该被做成一个库)
 
function v1() { ... }
function v2() { ... }
 
export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

Default exports
现在广泛使用的模块系统有CommonJS、AMD两种,设计出来的新标准可以与这两种模块进行交互。所以假设你有一个Node项目,你已经执行了npm install lodash,你的ES6模块可以从Lodash中导入独立的函数:

import {each, map} from "lodash";
 
each([3, 2, 1], x => console.log(x));

但是也许你已经习惯看到_.each的书写方式而不想直接用each函数呢?或者你就真的想导入整个_函数呢,毕竟_对于Lodash而言至关重要。

针对这种情况,你可以换用一种稍微不太一样的方法:不用花括号来导入模块。

import _ from "lodash";

这种简略的表达方法等价于import {default as _} from “lodash”;。在ES6的模块中导入的CommonJS模块和AMD模块都有一个默认的导出,如果你用require()加载这些模块也会得到相同的结果——exports对象。

ES6模块不只导出CommonJS模块,它的设计逻辑为你提供导出不同内容的多种方法,默认导出的是你得到的所有内容。举个例子,在用这种写法的时候,据我所知,著名的colors包就没有任何针对ES6的支持。像大多数npm上的包一样,它是诸多CommonJS模块的集合,但是你可以正确地将它导入到你的ES6代码中。

// `var colors = require("colors/safe");`的ES6等效代码
import colors from "colors/safe";

如果你想让自己的ES6模块有一个默认的导出,实现的方法很简单,默认导出与其它类型的导出相似,没有什么技巧可言,唯一的不同之处是它被命名为“default”。你可以用我们刚才讨论的重命名语法来实现:

let myObject = {
  field1: value1,
  field2: value2
};
export {myObject as default};

这种简略的表达方法看起来更清爽:

export default {
  field1: value1,
  field2: value2
};

关键字export default后可跟随任何值:一个函数、一个类、一个对象字面量,只要你能想到的都可以。

模块对象
很抱歉新特性有点儿多,但JavaScript不是唯一这样做的语言:出于某些原因,每一种语言中的模块系统都有这么一堆又独立又小,虽然无聊但是很方便的特性。不过还好,我们只剩一样东西没讲了。好吧,是两样。

import * as cows from "cows";

当你import *时,导入的其实是一个模块命名空间对象,模块将它的所有属性都导出了。所以如果“cows”模块导出一个名为moon()的函数,然后用上面这种方法“cows”将其全部导入后,你就可以这样调用函数了:cows.moo()。

聚合模块
有时一个程序包中主模块的代码比较多,为了简化这样的代码,可以用一种统一的方式将其它模块中的内容聚合在一起导出,可以通过这种简单的方式将所有所需内容导入再导出:

// world-foods.js - 来自世界各地的好东西
 
// 导入"sri-lanka"并将它导出的内容的一部分重新导出
export {Tea, Cinnamon} from "sri-lanka";
 
// 导入"equatorial-guinea"并将它导出的内容的一部分重新导出
export {Coffee, Cocoa} from "equatorial-guinea";
 
// 导入"singapore"并将它导出的内容全部导出
export * from "singapore";

这些export-from语句每一个都好比是在一条import-from语句后伴随着一个export。与真正的导入内容的方法不同的是,这些导入内容再重新导出的方法不会在作用域中绑定你导入的内容。如果你打算用world-foods.js中的Tea来写一些代码,可别用这种方法导入模块,你会发现当前模块作用域中根本找不到Tea。

如果从“singapore”导出的任何名称碰巧与其它的导出冲突了,可能会触发一个错误,所以使用export *语句的时候要格外小心。

呼!终于讲完了所有的语法!现在来讲一些有趣的内容。

import实际都做了些什么?
如果我说它什么都没做,你敢信?

哦,看来你没那么容易上当啊。好吧,你相信标准里面通常都不会规定import的行为么?如果真是这样,那这是件好事儿么?

ES6将模块加载过程的细节完全交由最终的实现来定义,模块执行的其它部分倒是在规范中有详细定义。

粗略地讲,当你通知JS引擎运行一个模块时,它一定会按照以下四个步骤执行下去:

语法解析:阅读模块源代码,检查语法错误。
加载:递归地加载所有被导入的模块。这也正是没被标准化的部分。
连接:每遇到一个新加载的模块,为其创建作用域并将模块内声明的所有绑定填充到该作用域中,其中包括由其它模块导入的内容。
如果你的代码中有import {cake} from "paleo"这样的语句,而此时“paleo”模块并没有导出任何“cake”,你就会触发一个错误。这实在是太糟糕了,你都快要运行模块中的代码了,都是cake惹的祸!
运行时:最终,在每一个新加载的模块体内执行所有语句。此时,导入的过程就已经结束了,所以当执行到达有一行import声明的代码的时候……什么都没发生!

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值