目录
前言
export命令
输出变量
输出函数/类
export中的as别名
export必须一一对应
export接口的响应性
注意
import命令
import命令的语法
import命令里的as别名
import的只读性
import命令具有提升性
import的一些约定
import的静态执行
import的唯一执行性
模块的整体加载
方法一
方法二
注意
export default命令
export default语法
export default的另类输出
export与import的复合写法
跨模块常量
前言
ES6标准---【一】【学习ES6看这一篇就够了!!】_es6学习-CSDN博客
ES6标准---【二】【学习ES6看这一篇就够了!!】_es6中的includes-CSDN博客
ES6标准---【三】【学习ES6看这一篇就够了!!!】-CSDN博客
ES6标准---【四】【学习ES6标准看这一篇就够了!!!】_es6 有arguments 吗-CSDN博客
ES6标准---【五】【看这一篇就够了!!!】-CSDN博客
ES6标准---【六】【学习ES6标准看这一篇就够了!!!】-CSDN博客
ES6标准---【七】【学习ES6标准看这一篇就够了!!!】-CSDN博客
export命令
export命令用于规定模块的对外接口
一个模块是一个独立的文件,该文件内部的所有变量,外部无法获取
如果想要外部能够读取模块内部的某个变量(函数、类),就必须使用export关键字输出该变量(函数、类)
输出变量
// profile.js
// 第一种写法
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;// profile.js
// 第二种写法
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export { firstName, lastName, year };
在实际中,我们应优先使用第二种写法,这种写法可以一眼看出究竟输出了哪些变量
输出函数/类
输出函数/类直接export函数名/类名即可
function v1() { ... }
function v2() { ... }
export {v1,v2,v3};
- 一个例子
// profile.js
function test1() {console.log("hello,this istest1");
}
export {test1};// 测试html
<body><script type="module">import {test1} from "./JS/profile.js"test1();</script>
</body>
效果:
export中的as别名
通常情况下,export输出的变量/函数/类,是它们的名字,但是也可以使用as关键字重命名
function v1() { ... }
function v2() { ... }
export {v1 as streamV1,v2 as streamV2,v2 as streamLatestVersion
};
使用as关键字,重命名v1和v2函数的“对外接口名”
- 外部调用需要使用“对外接口名”
- 重命名后v2可以用不同的名字输出两次(但是调用两个“对外接口名”都是指v2函数)
export必须一一对应
export命令规定的是“对外接口名”,必须与模块内部的变量建立一一对应的关系
// 报错
export 1;
// 报错
var m = 1;
export m;// 三种正确的写法
// 方法一
export var m = 1;
// 方法二
var m = 1;
export {m};
// 方法三
var m = 1;
export {m as n};// 报错
function f() {}
export f;
// 正确
export function f() {};
// 正确
function f() {}
export {f};
export接口的响应性
export语句输出的接口,与其对应的值是动态绑定关系(某个变量的值在export输出后,如果改变了值,那么外部接口调用的值也是改变的)
即:“通过该接口,可以取到模块内部实时的值”
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);
- 上面代码变量foo的值,在500ms之后变成baz,下面是一个例子
// profile.js
export var data = 1;
setTimeout(() => data = 2,1000);// 测试html
<body><script type="module">import {data} from "./JS/profile.js"setInterval(() => console.log(data), 500);</script>
</body>
效果:
注意
export命令(包括后面的import命令)可以出现在模块的任何位置,只要处于模块顶层就可以
如果处于块级作用域(if语句、for语句、函数等等),就会报错
function test() {import {data} from "./JS/profile.js" //报错
}
效果:
import命令
import命令用于接收. >
?" 用export命令定义了模块的对外接口后,其它JS/HTML文件就可以通过import命令使用这个模块
//profile.js
var x = 1,y = 2,z = 3;
export {x,y,z};//main.js
import {x,y,z} from "./JS/progile.js";
console.log("x+y+z =",x+y+z);
import命令的语法
import语法:
import {变量a,变量b...} from "url"
其中,url可以是:
- 绝对路径
- 相对路径
import命令里的as别名
import与export一样,允许对接收到的的输出接口(也叫import的输入接口)起一个别名
import {x as m} from "./JS/profile.js";
- 起别名后,原先的名字不可以使用
import {x as m} from "./JS/profile.js";console.log(x); //报错,as别名后,原先的名字不能使用
console.log(m); //正确
import的只读性
import命令输入的“变量”、“函数”、“类”都是只读的,不允许在外部修改它们的值
import {x as m} from "./JS/profile.js";
m = 10; //报错,不允许在外部修改它的值
- 但是如果变量是一个“对象”,改写变量的属性,是允许的
- 尽管对象的属性可以改写,但是不建议这样做,不利于排错,因此全部归类为“只读的”是比较稳妥的办法
import命令具有提升性
import命令具有提升效果,会提升到整个模块的头部,首先执行
原因是:“import命令是编译阶段运行的,在代码运行之前”
下面的代码不会报错,因为import命令具有提升效果
foo();
import { foo } from 'my_module';
import的一些约定
import的静态执行
import是静态执行,所以不能使用表达式和变量(即:只有在运行时才能得到结果的语法结构)
// 报错
import { 'f' + 'oo' } from 'my_module';
// 报错
let module = 'my_module';
import { foo } from module;
// 报错
if (x === 1) {import { foo } from 'module1';
} else {import { foo } from 'module2';
}
import的唯一执行性
如果多次重复加载“相同的一个js文件”,那么只会执行一次,而不会执行多次
import { foo } from 'my_module';
import { bar } from 'my_module';
// 等同于
import { foo, bar } from 'my_module';
模块的整体加载
除了指定加载某个具体的值,我们还可以整体加载一整个js文件(类似于ES6以前使用script导入一整个js文件),用星号【*】指定一个对象,所有js文件的输出值都在这个对象里面
例如,要整体导入一个“profile.js”文件,可以有两个方法
方法一
手动指定profile.js文件中所有的变量、函数、类
// profile.js
var a = 1;
function myFunction () {conosle.log("这里是myFunction()");
}
export {a,myFunction};//main.js 在这里加载这个模块
import {a,myFunction} from "./JS/profile.js";console.log("a的值为:",a);
myFunction();
方法二
使用星号【*】导入
// profile.js
var a = 1;
function myFunction () {conosle.log("这里是myFunction()");
}
export {a,myFunction};//main.js 在这里加载这个模块
import * as profile from "./JS/profile.js";console.log("a的值为:",profile.a);
profile.myFunction();
注意
虽然使用星号整体导入一整个js文件并把这个文件赋值给一个对象,但是这个对象却不能添加、修改、删除属性,即这个对象是“只读的”
下面的写法都是不允许的:
import * as profile from "./JS/profile.js";//下面两行都是不允许的
profile.a = 2;
profile.otherFunction = function() {};
export default命令
使用import命令时,用户需要知道“输出接口名”,否则无法加载
为此,我们引入export default命令,使用该命令可以不必在意“输出接口名”,直接上手!!
export default的默认输出是一个函数或变量
export default语法
export default function () {...};
export default 变量;
// profile.js
export default function () {console.log("这里是default function()");
}
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字(自取)
// main.js
import importFunction from './JS/profile.js';
importFunction();
效果:
需要注意的是,导入默认函数,import后面不必再加“花括号”
- export default命令也可以用在非匿名函数前,不过此时非匿名函数名在外部是无效的,加载时,视同匿名函数加载
// export-default.js
export default function foo() {console.log('foo');
}
// 或者写成
function foo() {console.log('foo');
}
export default foo;
export default的另类输出
本质上,export default就是输出一个叫做“default”的变量或方法,然后系统允许你为它设置任意名字
因此,下面的写法是有效的:
// modules.js
function add(x, y) {return x * y;
}
export {add as default};
// 等同于
// export default add;
// app.js
import { default as foo } from 'modules';
// 等同于
// import foo from 'modules';
- export export后面不能跟变量声明语句
// 正确
export var a = 1;
// 正确
var a = 1;
export default a;
// 错误
export default var a = 1;
- 我们可以直接将一个值直接写在export default之后
// 正确
export default 42;
// 报错
export 42;
- export default也可以用来输出类
// MyClass.js
export default class { ... }
// main.js
import MyClass from 'MyClass';
let o = new MyClass();
export与import的复合写法
如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起
export { foo, bar } from 'my_module';
// 可以简单理解为
import { foo, bar } from 'my_module';
export { foo, bar };
注意【重要】:
- foo和bar并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用“foo”和“bar”
模块的接口改名和整体输出,也可以用这种写法:
// 接口改名
export { foo as myFoo } from 'my_module';
// 整体输出
export * from 'my_module';
默认接口的写法:
转发默认接口,需要添加“花括号”
export { default } from 'foo';
具名接口改为默认接口的写法:
export { es6 as default } from './someModule';
// 等同于
import { es6 } from './someModule';
export default es6;
默认接口改为具名接口:
export { default as es6 } from './someModule';
转发一整个js文件:
export * as ns from "mod";
// 等同于
import * as ns from "mod";
export {ns};
注意:使用“export *”会忽略default方法
跨模块常量
const声明的常量只在当前代码块有效,如果想设置跨模块的常量(即跨多个文件),或者说一个值要被多个模块共享,可以采用下面的写法:
// constants.js 模块
export const A = 1;
export const B = 3;
export const C = 4;
// test1.js 模块
import * as constants from './constants';
console.log(constants.A); // 1
console.log(constants.B); // 3
// test2.js 模块
import {A, B} from './constants';
console.log(A); // 1
console.log(B); // 3
- 如果要使用的常量非常多,可以搭建一个专门的“constants”目录,将各种常量写在不同的文件里面,保存在该目录下:
// constants/db.js
export const db = {url: 'http://my.couchdbserver.local:5984',admin_username: 'admin',admin_password: 'admin password'
};
// constants/user.js
export const users = ['root', 'admin', 'staff', 'ceo', 'chief', 'moderator'];
- 然后将这些文件输出的常量,合并在一个js文件里:
// constants/myindex.js
export {db} from './db';
export {users} from './users';
- 使用的时候,直接加载这个js文件即可:
// script.js
import {db, users} from './constants/myindex.js';