博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ES6中export , export default , import模块系统总结
阅读量:5905 次
发布时间:2019-06-19

本文共 3385 字,大约阅读时间需要 11 分钟。

最近在学习使用Webpack3的时候发现,它已经可以在不使用babel的情况下使用ES6的模块加载功能了。(不包括webpack.config.dev.js文件。

因为它是是webpack的配置文件,是nodejs直接运行处理的。所以仍需使用CommonJS规范,其他被webpack编译的js模块可以使用es6写法。)

说到ES6的模块加载功能,我们先复习一下CommonJS规范吧:

一  . CommonJS规范规定,在每个模块内的module变量代表当前模块。这个变量的module.exports属性是对外开放的接口。

加载某个模块,其实是加载此模块的module.exports属性。

exampleA.js
var x = 5;var addX = function (value) {  return value + x;};module.exports.x = x;module.exports.addX = addX;

上面代码通过module.exports对外暴露出变量x和函数addX

每个模块的module对象默认拥有这些属性:

  module.id 模块的识别符,通常是带有绝对路径的模块文件名。

  module.filename 模块的文件名,带有绝对路径。

  module.loaded 返回一个布尔值,表示模块是否已经完成加载。

  module.parent 返回一个对象,表示调用该模块的模块。  

  module.children 返回一个数组,表示该模块要用到的其他模块。

  module.exports 表示模块对外输出的值。

. export变量:为了方便,每个模块内都有一个指向module.exports的对象 exports。

.require方法:用于加载模块。

读取并执行一个JavaScript文件,然后返回该模块的exports对象。

exampleB.js
var exampleA = require('./exampleA.js');//加载上文的模块console.log(exampleA.x); // 5console.log(exampleA.addX(1)); // 6

以上是Commonjs的常用功能。其他功能参考阮大神的:

 

ES6中模块规范

. export方法:

用法1:

// profile.jsexport var firstName = 'Michael';export var lastName = 'Jackson';export var year = 1958;

用法2:

// profile.jsvar firstName = 'Michael';var lastName = 'Jackson';var year = 1958;
export { firstName, lastName, year};
//export { firstName as obj1, lastName as obj2, year as obj3};//可以使用as关键字重命名

与CommonJS不同的是:export语句的输出接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

. import方法

import {firstName, lastName, year} from './profile.js'; //import { lastName as surname } from './profile.js'; //import * as profile from './profile.js';

import命令具有提升效果,会提升到整个模块的头部,首先执行。

. export default 方法

// export-default.jsexport default function () {  console.log('foo');} //其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。
// import-default.jsimport customName from './export-default';customName(); // 'foo'

上面的import方法,可以用任意名称指向export-default.js(指向)输出的方法,这时就不需要知道原模块输出的函数名。

这时import命令后面,不使用大括号。

如果想在一条import语句中,同时引入default接口和其他接口,可以写成下面这样。

import _, { each, each as forEach } from 'lodash';

. import() 方法

动态加载模块,返回一个 Promise 对象。(nodejs中使用require.ensure实现)

import('./someModules.js')  .then(module => {    console.log(module);  })  .catch(err => {
  console.log(err); });

 

ES6模块与CommonJS模块的区别

. CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。

CommonJS 模块是运行时加载js文件,ES6 模块是编译时加载模块,输出接口。

. 第二个差异是因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,

它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。(然而nodejs中对ES6模块的实现任是基于自身的CommonJS 并没有实现静态加载)

CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。

//CommonJS // lib.jsvar counter = 3;function incCounter() {  counter++;}module.exports = {  counter: counter,  incCounter: incCounter,};

上面代码输出内部变量counter和改写这个变量的内部方法incCounter。然后,在main.js里面加载这个模块。

//CommonJS // main.jsvar mod = require('./lib');console.log(mod.counter);  // 3mod.incCounter();console.log(mod.counter); // 3

上面代码说明,lib.js模块加载以后,它的内部变化就影响不到输出的mod.counter了。这是因为mod.counter是对模块内counter对象值的拷贝。

除非写成一个函数,才能实时获取mod.counter的变动。

//CommonJS // lib.jsvar counter = 3;function incCounter() {  counter++;}module.exports = {  get: counter() {    return counter  },  incCounter: incCounter,};

ES6模块:

// lib.jsexport let counter = 3;export function incCounter() {  counter++;}// main.jsimport { counter, incCounter } from './lib';console.log(counter); // 3incCounter();console.log(counter); // 4

结果说明,ES6 模块输入的变量counter是活的(闭包),完全反应其所在模块lib.js内部的变化。

 

注:参考阮一峰大神的《ECMAScript6入门》。

转载于:https://www.cnblogs.com/zhuxiaoweb/p/8298140.html

你可能感兴趣的文章
HTML
查看>>
java继承捡漏
查看>>
java文件监控[转]
查看>>
vim学习笔记(9):vim显示文件名
查看>>
C#中常用的经典文件操作方法
查看>>
P2278 操作系统
查看>>
JSP01
查看>>
button按钮居中
查看>>
webpack: require.ensure与require AMD的区别
查看>>
Azkaban
查看>>
git推送文件到远程仓库
查看>>
MySql数据库的常用命令
查看>>
Android刷机教程之LG Nexus 5X线刷官方Nexus系列教程
查看>>
Python-正则表达式
查看>>
mvc自定义全局异常处理
查看>>
第一部分UI 2.视图之间跳转使用UITabBarController
查看>>
图像处理之基础---内积和外积
查看>>
高清接口芯片---gv7600、sii9135
查看>>
题解 20181029测试:T4 ambassador
查看>>
consul与docker的使用
查看>>