变量的解构赋值

140 阅读3分钟

变量的解构赋值

基础用法

  1. 基础概念 所谓解构是指用一个类似数组或对象字面量的语法,将数组或对象(迭代器)的属性赋值给变量。当使用数组解构时,被解构的对象一定要包含一个迭代器。
let [a, b, c] = [1, 2, 3]
console.log(a, b, c) // => 1 2 3

let {prop1: d, prop2: e} = {prop1: 1, prop2: 2}
console.log(d, e) // => 1 2
  1. 迭代解构 所谓迭代解构是指将属性值为对象的值解构赋值给同为对象的变量,从而实现解构的深层次属性赋值。
let [a, [c, d]] = [1, [2, 3]]
console.log(a, b, c) // => 1 2 3

let {prop1: d, prop2: {prop3: e}} = {prop1: 1, prop2: {prop3: 2}}
console.log(d, e) // => 1 2
  1. 对象解构的简写 对象解构的简写来源于es6中对象属性赋值简写的方式,即给一个对象的属性赋值时,当属性名和属性值所对应的变量名相同时,则可以简写。
let prop1 = 1
let obj = {prop1}
console.log(obj) // => {proop1: 1}

let {prop2} = {prop2: 2}
console.log(prop2) // => 2
  1. 非声明式变量解构 对于以花括号{开头的语句,浏览器解释时默认会认为是块作用域,所以对于非声明式的变量解构赋值,应加上中括号,让引擎识别此是表达式。
({a, b} = {a: 1, b: 2})

默认值

解构赋值适用于数组和对象类型,对可转化为基础包装类型的string number boolean会被转化成基础包装类型再进行解构。但对于null undefinded没有基础包装类型的原始类型会报错。为了解决[]空数组解构时传递给函数参数时报错,故希望能对函数参数赋值初始值的想法,于是出现了默认值语法。

let [a, b, c] = 'abc'
console.log(a, b, c) // => a b c

// 以下六种赋值方式都会报错,null\undefinded不能转化为对象,NaN/false/1转化为对象后无Iterator接口,{}本身无Iterator接口
let [d] = null // SyntaxError
let [foo] = 1 // SyntaxError
let [foo] = NaN // SyntaxError
let [foo] = false // SyntaxError
let [foo] = undefinded // SyntaxError
let [foo] = {} //SyntaxError

let [bar = 1, baz = 2] = []
console.log(bar, baz)  // => 1 2

// 只有判断属性值强等于`undefinded`才会启用默认值
let {prop1 = 1} = {prop1: undefinded}
console.log(prop1) // => 1
// null不等于undefinded,所以是有效的赋值
let {a = 1} = {a: null}
console.log(a) // => null

let {prop2: a = 1} = {prop2: 2}
console.log(prop2) // => 2

let {x = y, y = 1} = {} // Syntax报错,采用let声明,y还未声明 
let {x = y, y = 1} = {x: 1, y: 2} // 不报错,默认值只会在属性值返回undefinded时才赋值
var {x = y, y = 1} = {} // undefined 1 不报错, 存在变量提升

解构的由来

长期以来对于变量的赋值都是单一的,要获取数组的某一项值/对象中某一属性值,只能通过点运算符或取值操作符。为了解决这种复杂的操作,于是出现了一种的新的js表达式,叫做解构。

解构能解决什么问题

  1. 数组解构
  • 简化变量交换
let a = 1
let b = 2
[a, b] = [b, a]
  • 解析函数返回值
function foo () {
    return [1, 3, 2]
}
let [a, , c] = foo() // 以数组形式返回多个值,忽略函数返回值的某一项
  • 将剩余数组赋值给某一变量
let [a, b, ...c] = [1, 2, 3, 4] // 注意不定参数解构数组时,只能用在最后一项
console.log(c) // => [3, 4]
  1. 对象
  • 优化函数传参
// 函数声明,解构对象赋值变量
jquery.ajax = function ({
    type = 'get',
    url,
    async = true
}) {}
// 函数调用,传入对象参数,没有顺序要求
jquery.ajax({
    type: 'post',
    async: false,
    url: '/a/b'
})
  • 解析函数返回值
function foo () {
    return {a: 1, b: 2}
}
const {a, b} = foo()
  • API优化---import模块
const doSomething = function () {}
const doAnything = function () {}
export {
    doSomething,
    doAnything()
}

import {doAnything} from '/' // 只引入需要的接口

参考文献

  1. 阮一峰的《es6入门》es6.ruanyifeng.com/#docs/let
  2. 《深入浅出es6》系列文章
  3. MDN文档 developer.mozilla.org/zh-CN/docs/…