ES6 导入和导出速查表
在 ES6 出现之前,我们在单个 HTML 文件中使用多个脚本标签来导入不同的 JavaScript 文件,如下所示:
<script type="text/javascript" src="home.js"></script>
<script type="text/javascript" src="profile.js"></script>
<script type="text/javascript" src="user.js"></script>
因此,如果我们在不同的 JavaScript 文件中有一个同名的变量,就会产生命名冲突,并且您期望的值将不是您得到的实际值。
ES6 通过模块的概念解决了这个问题。
我们用 ES6 编写的每个 JavaScript 文件都称为一个模块。我们在每个文件中声明的变量和函数只有在我们明确地将它们从该文件中导出并导入到另一个文件中时,才能在其他文件中使用。
因此,文件中定义的函数和变量对于每个文件来说都是私有的,在我们导出它们之前不能在文件外部访问。
出口有两种类型:
- 命名导出:单个文件中可以有多个命名导出
- 默认导出:单个文件中只能有一个默认导出
JavaScript 中的命名导出
要将单个值导出为命名导出,我们可以像这样导出:
export const temp = "This is some dummy text";
如果我们需要导出多个内容,我们可以将导出语句写在单独的一行,而不是放在变量声明前面。我们在花括号中指定要导出的内容。
const temp1 = "This is some dummy text1";
const temp2 = "This is some dummy text2";
export { temp1, temp2 };
请注意,导出语法不是对象字面量语法。因此,在 ES6 中,我们不能像这样使用键值对来导出内容:
// This is invalid syntax of export in ES6
export { key1: value1, key2: value2 }
为了导入我们作为命名导出导出的内容,我们使用以下语法:
import { temp1, temp2 } from './filename';
请注意,从文件导入某些内容时,我们不需要.js
在文件名中添加扩展名,因为默认情况下会考虑扩展名。
// import from functions.js file from current directory
import { temp1, temp2 } from './functions';
// import from functions.js file from parent of current directory
import { temp1 } from '../functions';
这是一个代码沙盒演示。
需要注意的一点是,导出时使用的名称必须与导入时使用的名称相匹配。
因此,如果您要导出为:
// constants.js
export const PI = 3.14159;
然后在导入时必须使用与导出时相同的名称:
import { PI } from './constants';
您不能使用任何其他名称,例如:
import { PiValue } from './constants'; // This will throw an error
但是如果您已经拥有与导出变量同名的变量,则可以在导入时使用重命名语法,如下所示:
import { PI as PIValue } from './constants';
这里我们将其重命名为PI
,PIValue
因此现在不能使用PI
变量名。相反,我们必须使用PIValue
变量来获取 PI 的导出值。
我们还可以在导出时使用重命名语法:
// constants.js
const PI = 3.14159;
export { PI as PIValue };
然后在导入时我们必须PIValue
这样使用:
import { PIValue } from './constants';
要将某些内容作为命名导出进行导出,我们必须先声明它。
export 'hello'; // this will result in error
export const greeting = 'hello'; // this will work
export { name: 'David' }; // This will result in error
export const object = { name: 'David' }; // This will work
我们导入多个命名导出的顺序并不重要。
看一下下面的validations.js
文件:
// utils/validations.js
const isValidEmail = function(email) {
if (/^[^@ ]+@[^@ ]+\.[^@ \.]{2,}$/.test(email)) {
return "email is valid";
} else {
return "email is invalid";
}
};
const isValidPhone = function(phone) {
if (/^[\\(]\d{3}[\\)]\s\d{3}-\d{4}$/.test(phone)) {
return "phone number is valid";
} else {
return "phone number is invalid";
}
};
function isEmpty(value) {
if (/^\s*$/.test(value)) {
return "string is empty or contains only spaces";
} else {
return "string is not empty and does not contain spaces";
}
}
export { isValidEmail, isValidPhone, isEmpty };
我们index.js
使用这些函数如下所示:
// index.js
import { isEmpty, isValidEmail } from "./utils/validations";
console.log("isEmpty:", isEmpty("abcd")); // isEmpty: string is not empty and does not contain spaces
console.log("isValidEmail:", isValidEmail("abc@11gmail.com")); // isValidEmail: email is valid
console.log("isValidEmail:", isValidEmail("ab@c@11gmail.com")); // isValidEmail: email is invalid
这是一个代码沙盒演示。
如你所见,我们可以只导入需要导出的内容,并且顺序不限,因此无需检查在另一个文件中导出的顺序。这就是命名导出的魅力所在。
JavaScript 中的默认导出
正如我之前所说,单个文件中最多可以有一个默认导出。
但是,您可以在一个文件中组合多个命名导出和一个默认导出。
要声明默认导出,我们在导出关键字前面添加默认关键字,如下所示:
//constants.js
const name = 'David';
export default name;
要导入默认导出,我们不需要像在命名导出中那样添加花括号,如下所示:
import name from './constants';
如果我们有多个命名导出和一个默认导出,如下所示:
// constants.js
export const PI = 3.14159;
export const AGE = 30;
const NAME = "David";
export default NAME;
然后,为了在一行上导入所有内容,我们只需要在花括号前使用默认导出的变量。
// NAME is default export and PI and AGE are named exports here
import NAME, { PI, AGE } from './constants';
默认导出的一个特点是我们可以在导入时更改导出变量的名称:
// constants.js
const AGE = 30;
export default AGE;
在另一个文件中,我们可以在导入时使用另一个名称
import myAge from ‘./constants’;
console.log(myAge); // 30
在这里,我们将默认导出变量的名称从AGE
更改为myAge
。
这是可行的,因为只能有一个默认导出,所以您可以随意命名它。
关于默认导出还需要注意的是,export default 关键字不能位于变量声明之前,如下所示:
// constants.js
export default const AGE = 30; // This is an error and will not work
因此我们必须在单独的行上使用 export default 关键字,如下所示:
// constants.js
const AGE = 30;
export default AGE;
但是,我们可以导出默认值而不声明变量,如下所示:
//constants.js
export default {
name: "Billy",
age: 40
};
并在另一个文件中像这样使用它:
import user from './constants';
console.log(user.name); // Billy
console.log(user.age); // 40
还有另一种方法可以使用以下语法导入文件中导出的所有变量:
import * as constants from './constants';
在这里,我们导入了所有命名的和默认的导出,并将其constants.js
存储在constants
变量中。所以,constants
现在会变成一个对象。
// constants.js
export const USERNAME = "David";
export default {
name: "Billy",
age: 40
};
在另一个文件中,我们按如下方式使用它:
// test.js
import * as constants from './constants';
console.log(constants.USERNAME); // David
console.log(constants.default); // { name: "Billy", age: 40 }
console.log(constants.default.age); // 40
这是一个代码沙盒演示。
如果您不想在单独的行上导出默认导出和命名导出,您可以将其组合起来,如下所示:
// constants.js
const PI = 3.14159;
const AGE = 30;
const USERNAME = "David";
const USER = {
name: "Billy",
age: 40
};
export { PI, AGE, USERNAME, USER as default };
在这里,我们将导出USER
为默认导出,将其他导出为命名导出。
在另一个文件中,您可以像这样使用它:
import USER, { PI, AGE, USERNAME } from "./constants";
这是一个代码沙盒演示。
结论
- 在 ES6 中,一个文件中声明的数据不能被另一个文件访问,除非将其从该文件导出并导入到另一个文件中。
- 如果文件中只有单个内容需要导出,例如类声明,则使用默认导出,否则使用命名导出。我们也可以在一个文件中组合使用默认导出和命名导出。
感谢阅读
从 ES6 开始,JavaScript 中有很多有用的新增功能,例如
- ES6 解构
- 导入和导出语法
- 箭头函数
- 承诺
- 异步/等待
- 可选的链接运算符等等。
您可以在我的《掌握现代 JavaScript》一书中详细了解有关所有 ES6+ 功能的所有信息。
在此处查看本书的免费预览内容。
此外,您还可以查看我的免费 “React Router 简介”课程,从头开始学习“React Router”。
想要定期了解有关 JavaScript、React 和 Node.js 的最新内容吗?请在 LinkedIn 上关注我。
文章来源:https://dev.to/myogeshchavan97/es6-import-and-export-cheatsheet-3op5