详解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 相关文章推荐
解放web程序员的输入验证
Oct 06 Javascript
javascript下对于事件、事件流、事件触发的顺序随便说说
Jul 17 Javascript
兼容FF和IE的动态table示例自写
Oct 21 Javascript
如何实现移动端浏览器不显示 pc 端的广告
Oct 15 Javascript
AngularJS基础 ng-if 指令用法
Aug 01 Javascript
使用Bootstrap Tabs选项卡Ajax加载数据实现
Dec 23 Javascript
js实现把图片的绝对路径转为base64字符串、blob对象再上传
Dec 29 Javascript
jQuery弹出层插件popShow用法示例
Jan 23 Javascript
Vue2.0实现1.0的搜索过滤器功能实例代码
Mar 20 Javascript
在使用JSON格式处理数据时应该注意的问题小结
May 20 Javascript
微信小程序button组件使用详解
Jan 31 Javascript
利用d3.js制作连线动画图与编辑器的方法实例
Sep 05 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函数
2008/10/03 PHP
typecho插件编写教程(六):调用接口
2015/05/28 PHP
php里array_work用法实例分析
2015/07/13 PHP
php实现购物车功能(上)
2020/07/23 PHP
php基于单例模式封装mysql类完整实例
2016/10/18 PHP
Chosen 基于jquery的选择框插件使用方法
2012/05/30 Javascript
jQuery操作input type=radio的实现代码
2012/06/14 Javascript
利用javascript实现禁用网页上所有文本框,下拉菜单,多行文本域
2013/12/14 Javascript
Iframe实现跨浏览器自适应高度解决方法
2014/09/02 Javascript
AngularJS语法详解(续)
2015/01/23 Javascript
JQuery基础语法小结
2015/02/27 Javascript
Angular Js文件上传之form-data
2015/08/28 Javascript
bootstrap快速制作后台界面
2016/12/05 Javascript
Vue+axios 实现http拦截及路由拦截实例
2017/04/25 Javascript
vue2项目使用sass的示例代码
2017/06/28 Javascript
react-router4 嵌套路由的使用方法
2017/07/24 Javascript
Router解决跨模块下的页面跳转示例
2018/01/11 Javascript
vue 使用自定义指令实现表单校验的方法
2018/08/28 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
javascript删除数组元素的七个方法示例
2019/09/09 Javascript
Vue数据双向绑定底层实现原理
2019/11/22 Javascript
Python中List.index()方法的使用教程
2015/05/20 Python
Python之列表的插入&替换修改方法
2018/06/28 Python
python 修改本地网络配置的方法
2019/08/14 Python
Django bulk_create()、update()与数据库事务的效率对比分析
2020/05/15 Python
python 根据列表批量下载网易云音乐的免费音乐
2020/12/03 Python
使用HTML5做的导航条详细步骤
2020/10/19 HTML / CSS
Ryderwear美国官网:澳大利亚高端健身训练装备品牌
2018/04/24 全球购物
乌克兰数字设备、配件和智能技术的连锁商店:KTC
2020/08/18 全球购物
英语师范专业毕业生自荐信
2013/09/21 职场文书
财务管理个人自荐书范文
2013/11/24 职场文书
逃课打麻将检讨书
2014/10/05 职场文书
环卫工作汇报材料
2014/10/28 职场文书
廉洁自律准则学习心得体会
2016/01/13 职场文书
传单、海报早OUT了,另类传单营销方案送给你!
2019/07/15 职场文书
详解Redis复制原理
2021/06/04 Redis