Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

02--ES6模块 #2

Open
Open
@simplexcspp

Description

@simplexcspp

一、ES6模块体系简述

  • 1、上一篇“ javascript模块化进程 ”中也说到:历史上,JavaScript 一直没有模块体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。ES6之前,社区制定了一些模块加载方案,最主要的有 CommonJS(服务器)和 AMD/CMD(浏览器)两种。

  • 2、ES6在语言标准的层面上,实现了模块功能,完全可以取代 CommonJS 和 AMD(CMD) 规范,成为浏览器和服务器通用的模块解决方案

二、ES6模块

  • 1、ES6 模块与CommonJS 、 AMD 模块区别

    • ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量

    • CommonJS 和 AMD 模块,都只能在运行时确定模块依赖关系(运行时加载),因为只有运行时才能得到模块对应的对象(如,CommonJS 模块就是对象,输入时必须查找对象属性)。

    • ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入

  • 2、ES6 模块特性

    • 一个模块就是一个独立的文件,其内部的所有变量,外部无法获取

    • 编译时加载或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高

    • ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入,因此没法引用模块本身

  • 3、ES6模块构成的两个关键字

    • export:规定模块的对外接口
    • import:输入模块提供的功能
  • 4、export关键字

  • A、输出变量、函数、类

// 直接输出export const name = 'jackxu';export const add = (x = 0, y = 0) => {    return x + y;};export class Hello {    sayHi() {        console.log('Hi~!');    }}// 统一输出const name = 'jackxu';const add = (x = 0, y = 0) => {    return x + y;};class Hello {    sayHi() {        console.log('Hi~!');    }}export { name, add, Hello }
  • B、输出的变量就是原变量名,可以使用as关键字重命名
const name = 'jackxu';const add = (x = 0, y = 0) => {    return x + y;};class Hello {    sayHi() {        console.log('Hi~!');    }}export {    name as ESName,    add as addTwo,    Hello as Hi}
  • 5、export使用注意事项

  • A、export规定模块的对外接口,必须与模块内部的变量建立一一对应的关系

// 错误写法const add = (x = 0, y = 0) => {    return x + y;};export add;export 123;

image

//  正确写法const add = (x = 0, y = 0) => {    return x + y;};const A = 1;export { add, A }
  • B、export命令可以出现在模块的任何位置,但必须处于模块顶层
const fn = () => {    export const a = 'bar';};fn();

image

  • 6、import关键字

  • A、加载模块提供的功能(输入模块提供的功能)

import { name, add, Hello } form '模块相对路径/模块绝对路径/模块文件名'

模块后缀.js可以省略,相对路径./不能省略

模块文件名,由于不带路径,必须进行配置(如webpack+nodejs路径配置)

如加载先前export输出变量:

// 加载多个变量import { name, add, Hello } form './class/test17';// 加载单个变量import { name } form './class/test17';
  • B、模块的整体加载:用星号 * 指定一个对象,所有输出值都加载在这个对象上面
import * as filters form '模块相对路径/模块绝对路径/模块文件名'

如整体加载先前export输出变量:

import * as test form './class/test17';

模块整体加载所在的那个对象(如上面test),应该是可以静态分析的,所以不允许运行时改变。

如修改先前export输出的函数add,虽然不会报错,但不应这么操作。

import * as test from './class/test17';test.cname = '李四';  // 不恰当写法test.add = () => 666;  // 不恰当写法
  • C、import命令具有提升效果,会提升到整个模块的头部,首先执行。

如先执行add,在import输入export输出的变量add

console.log(add(2));import { add } from './class/test17';
  • D、import语句会执行所加载的模块,如果多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。
import '../../assets/styles/collect.css' // 仅仅执行模块,但是不输入任何值
  • E、import是静态执行,所以不能使用表达式和变量(这些只有在运行时才能得到结果的语法结构)

如下使用变量和表达式的import操作都会报错:

import { 'n' + 'ame' } from './class/test17';

image

let module = './class/test17';import { name } from module;

image

const a = 1;a === 1 ? import { name } from './class/test17' : '';

image

  • 7、export default关键字

export输出的模块,import加载的时,需要知道加载的变量名、函数名或类名,否则无法加载。而实际业务中,很可能不知道具体变量名,这时候就需要使用export default关键字。

  • A、export default输出的模块,使用import加载的时候,变量名可以任意指定名字,但import后面不使用{}
//  export default输出const name = 'jackxu';const add = (x = 0, y = 0) => {    return x + y;};class Hello {    sayHi() {        console.log('Hi~!');    }}export default { name, add, Hello }// import 输入import test from './class/test17';console.log(test.name);console.log(test.add(3, 6));

B、export default也可输出非匿名函数,系统默认函数名在模块外部无效,加载的时候视同匿名函数加载

匿名函数:

//  export default输出export default (arr = []) => {    return arr.filter(item => item > 6);}// import 输入import filterArr from './class/test17';console.log(filterArr([1, 4, 6, 8, 9, 10]));

非匿名函数:

//  export default输出export default function filter_arr(arr = []) {    return arr.filter(item => item > 6);}// import 输入import filterArr from './class/test17';console.log(filterArr([1, 4, 6, 8, 9, 10]));
  • C、export default用于指定模块的默认输出,一个模块只能有一个默认输出,因此export default命令只能使用一次
const _A = 123,    _B = (...arg) => new Map().set('arg', arg);    export default _A;export default _B;

image

  • D、export default本质:输出一个名为default的变量或方法,然后系统允许为其任意取名

demo1:

// babel转码前export default () => {  console.log('山穷水尽,柳暗花明');}// babel转码后'use strict';Object.defineProperty(exports, "__esModule", {  value: true});exports.default = function () {  console.log('山穷水尽,柳暗花明');};

demo2:

// babel转码前const name = 'jackxu';const fn = () => 5;export default { name, fn };// babel转码后'use strict';Object.defineProperty(exports, "__esModule", {  value: true});var name = 'jackxu';var fn = function fn() {  return 5;};exports.default = { name: name, fn: fn };
  • E、export default其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句

错误写法:

export default const _B = 123;

image

正确写法:

const _B = 123;export default _B;// 对比exportexport const _B = 123;
export default  66;// 对比exportexport 66;  // 错误写法

主要参考资料:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp