详解ES6 export default 和 import语句中的解构赋值


Posted in Javascript onMay 28, 2019

解构赋值

有如下 config 对象

const config = {
 host: 'localhost',
 port: 80
}

要获取其中的 host 属性

let { host } = config

拆分成模块

以上两段代码,放到同一个文件当中不会有什么问题,但在一个项目中,config 对象多处会用到,现在把 config 对象放到 config.js 文件当中。

// config.js
export default {
 host: 'localhost',
 port: 80
}

在 app.js 中 import config.js

// app.js
import config from './config'

let { host } = config
console.log(host) // => localhost
console.log(config.host) // => localhost

上面这段代码也不会有问题。但在 import 语句当中解构赋值呢?

// app.js
import { host } from './config'

console.log(host) // => undefined

问题所在

import { host } from './config'

这句代码,语法上是没什么问题的,之前用 antd-init 创建的项目,在项目中使用下面的代码是没问题的。奇怪的是我在之后用 vue-cli 和 create-react-app 创建的项目中使用下面的代码都不能正确获取到 host。

// config.js
export default {
 host: 'localhost',
 port: 80
}

// app.js
import { host } from './config'
console.log(host) // => undefined

babel 对 export default 的处理

我用 Google 搜 'es6 import 解构失败',找到了下面的这篇文章:ES6的模块导入与变量解构的注意事项。原来经过 webpack 和 babel 的转换

在ES6中变量解构是这样的:

const a = { b: 1 }
const { b } = a

我们可以直接用解构赋值来获得对象的同名属性,等效于:

const b = a.b

除了变量的解构赋值,ES6的模块导入也提供了相似的语法:

import { resolve } from 'path'

如果使用webpack构建项目的话,注意这里的解构与普通变量的解构是有所区别的,比如在a.js里有以下代码:

export default {

 b: 1

}

如果按照普通变量的解构法则来导入这个包,即这种形式:

import { b } from './a'

是会发生错误的,并不能导出变量b。主要因为这和webpack的构建有关。使用模块导入时,当用webpack构建后,以上的

import { b } from './a'

变为了类似

a.default.b

可以看到变量b在a.default上,并不在a上,所以解构出来是undefined。如果要正确解构,则必须在模块内导出,即:

export const b = 1

这样的话,构建后的代码中,变量b即在a上,而不是在a.default上,从而能正确解构。

所以

export default {
 host: 'localhost',
 port: 80
}

变成了

module.exports.default = {
 host: 'localhost',
 port: 80
}

所以取不到 host 的值是正常的。那为什么 antd-init 建立的项目有可以获取到呢?

解决

再次 Google,搜到了GitHub上的讨论 。import 语句中的"解构赋值"并不是解构赋值,而是 named imports,语法上和解构赋值很像,但还是有所差别,比如下面的例子。

import { host as hostName } from './config' // 解构赋值中不能用 as

let obj = {
 a: {
 b: 'hello',
 }
}

let {a: {b}} = obj // import 语句中不能这样子写
console.log(b) // => helllo

这种写法本来是不正确的,但 babel 6之前可以允许这样子的写法,babel 6之后就不能了。

// a.js
import { foo, bar } from "./b"
// b.js
export default {
 foo: "foo",
 bar: "bar"
}

所以还是在import 语句中多加一行

import b from './b'
let { foo, bar } = b

或者

// a.js
import { foo, bar } from "./b"
// b.js
let foo = "foo"
let bar = "bar"
export { foo, bar }

或者

// a.js
import { foo, bar } from "./b"
// b.js
export let foo = "foo"
export let bar = "bar"

而 antd-init 使用了babel-plugin-add-module-exports,所以 export default 也没问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 防止表单重复提交代码
Jan 21 Javascript
IE无法设置短域名下Cookie
Sep 23 Javascript
Jquery设置attr的disabled属性控制某行显示或者隐藏
Sep 25 Javascript
jQuery实现仿腾讯视频列表分页效果的方法
Aug 07 Javascript
IE6兼容透明背景图片及解决方案
Aug 19 Javascript
VUEJS实战之利用laypage插件实现分页(3)
Jun 13 Javascript
Bootstrap基本组件学习笔记之下拉菜单(7)
Dec 07 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
Apr 13 Javascript
简单谈谈axios中的get,post方法
Jun 25 Javascript
基于复选框demo(分享)
Sep 27 Javascript
javascript对象3个属性特征
Nov 17 Javascript
二维码条形码生成的JavaScript脚本库
Jul 07 Javascript
jQuery实现高级检索功能
May 28 #jQuery
利用原生JS实现data方法示例代码
May 28 #Javascript
php结合js实现多条件组合查询
May 28 #Javascript
vue实现前台列表数据过滤搜索、分页效果
May 28 #Javascript
js 将线性数据转为树形的示例代码
May 28 #Javascript
React中使用外部样式的3种方式(小结)
May 28 #Javascript
vue实现多条件和模糊搜索功能
May 28 #Javascript
You might like
php微信开发之自定义菜单实现
2016/11/18 PHP
Prototype ObjectRange对象学习
2009/07/19 Javascript
nullJavascript中创建对象的五种方法实例
2013/05/07 Javascript
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
2013/08/13 Javascript
使用JSLint提高JS代码质量方法分享
2013/12/16 Javascript
javascript 通用loading动画效果实例代码
2014/01/14 Javascript
nodejs实现黑名单中间件设计
2014/06/17 NodeJs
jquery引用方法时传递参数原理分析
2014/10/13 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
JS实现css hover操作的方法示例
2017/04/07 Javascript
MvcPager分页控件 适用于Bootstrap
2017/06/03 Javascript
JS中的三个循环小结
2017/06/20 Javascript
微信小程序模板(template)使用详解
2018/01/31 Javascript
layUI实现三级导航菜单效果
2019/07/26 Javascript
JS性能优化实现方法及优点进行
2020/08/30 Javascript
微信小程序反编译的实现
2020/12/10 Javascript
python检测是文件还是目录的方法
2015/07/03 Python
Python的Tornado框架的异步任务与AsyncHTTPClient
2016/06/27 Python
深入理解NumPy简明教程---数组3(组合)
2016/12/17 Python
如何用itertools解决无序排列组合的问题
2017/05/18 Python
Anaconda下配置python+opencv+contribx的实例讲解
2018/08/06 Python
将python图片转为二进制文本的实例
2019/01/24 Python
英国儿童设计师服装的领先零售商:Base
2019/03/17 全球购物
美国中西部家用医疗设备商店:Med Mart(轮椅、踏板车、升降机等)
2019/04/26 全球购物
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
我有一个char * 型指针正巧指向一些int 型变量, 我想跳过它们。 为什么如下的代码((int *)p)++; 不行?
2013/05/09 面试题
人民调解员先进事迹材料
2014/05/08 职场文书
作风建设年活动实施方案
2014/10/24 职场文书
2014年就业工作总结
2014/11/26 职场文书
2014年高数考试作弊检讨书
2014/12/14 职场文书
银行求职自荐信范文
2015/03/04 职场文书
试用期解除劳动合同通知书
2015/04/16 职场文书
中学综治宣传月活动总结
2015/05/07 职场文书
格列佛游记读书笔记
2015/06/30 职场文书
深入理解CSS 中 transform matrix矩阵变换问题
2021/08/30 HTML / CSS
Python爬虫网络请求之代理服务器和动态Cookies
2022/04/12 Python