美文网首页
变量的解构赋值

变量的解构赋值

作者: CandyTong_ | 来源:发表于2017-09-25 20:15 被阅读0次

标签: ES6


  • ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值
  • 本质上属于“模式匹配”,只要等号两边模式相同,左边的变量就会被赋予相应的值

数组的解构赋值

基本用法

var [a, b, c] = [1, 2, 3]
a   // 1
b   // 2
c   // 3
  • 解构不成功,则解构不成功的变量的值为undefined
  • 不完全解构,即等号左边的模式只匹配等号右边数组的一部分,则解构依然成功
let [x, y] = [1, 2, 3]
x   // 1
y   // 2

对于数组解构赋值,如果等式右边不是可遍历结构(本身 / 转化后的对象具备Iterator接口),将会报错

// 报错,转化后的对象不具备Iterator接口
let [a] = 1
let [b] = false
// 报错,对象本身不具备Iterator接口
let [c] = {}        
// 解构成功,字符串能转换成类似数组的对象
let [d, e, f, g, h] = 'hello'

默认值

  • 解构允许指定默认值
var [x, y = 2] = [1]    // x=1,y=2
  • 使用严格相等运算符(===)判断一个位置是否有值,仅在严格等于undefined时,默认值生效
var [x = 1] = [undefined]   // x=1
var [y = 1] = [null]        // y=null,默认值不生效
由于`(null===undefined)`的值为false,所以默认值不生效,`y`的值为null
  • 如果默认值为一个表达式,那么这个表达式是惰性求值的,只有用到的时候才会求值
function f() {
    console.log(123)
}
let [x = f()] = [1]     // 无输出
  • 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [x = 1, y = x] = []     // x=1,y=1
let [a = b, b = 1] = []     // 报错

对象的解构赋值

基本用法

var { foo, bar } = { foo: 123, bar: 345 }
foo // 123
bar // 345
  • 数组解构,变量的取值取决于它的位置
  • 对象解构,变量必须与属性同名,才能得到正确的值
var { abc } = { foo: 123, bar: 345 }
abc // undefined

对象的解构赋值实际上是以下形式的简写

var { foo, bar } = { foo: 123, bar: 345 }   // 简写
var { foo: foo, bar: bar } = { foo: 123, bar: 345 }

对象解构赋值的内部机制,是先找到同名属性,然后再赋给相应的变量。
真正被赋值的是后者,而不是前者

var { foo: baz } = { foo: 123, bar: 345 }
baz // 123
foo // Error:foo is not defined

对一个已经声明的变量解构赋值,不能将大括号 { } 写在行首,避免 javascript 将其解析为代码块

var x
({ x } = { x: 1 })  // 正确写法
{ x } = { x: 1 }    // 错误写法

默认值

默认值生效的条件是,对象的属性严格等于undefined

var { message: msg = 123, x } = { message: undefined, x: null }
msg     // 123
x       // null

解构嵌套结构的对象

var node = {
    loc: {
        start: {
            line: 1,
            column: 5
        }
    }
}
var { loc: { start: { line, column } } } = node
line    // 1
column  // 5
loc     // Error
start   // Error

注意:loc 和 start 是模式,不是变量,因此不会被赋值

解构对象是嵌套的对象,而且子对象所在的父对象不存在,会报错

var { foo: { bar } } = {}

foo为父对象,bar为子对象,foo不存在,报错
原因很简单:foo这时为undefined,再取子属性bar就会报错

其他类型的解构赋值

字符串的解构赋值

字符串可以解构赋值,此时字符串被转换成了一个类似数组的对象

let [d, e, f, g, h] = 'hello'
var { length: len } = 'hello'
len     // 5

数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值或布尔值,则先转为对象
undefinednull无法转为对象,会报错

let { toString: s } = 123
s === Number.prototype.toString     // true
let { toString: s } = true
s === Boolean.prototype.toString    // true

函数参数的解构赋值

function add([x, y]) {
    return x + y
}
add([1, 2])     // 3

注意区分以下两种情况:

function move({ x = 0, y = 0 } = {}) {
    return [x, y]
}
move({ x: 3, y: 1 })    // { x: 3, y: 1 }
move({ x: 3})           // { x: 3, y: 0 }
move({})                // { x: 0, y: 0 }
move()                  // { x: 0, y: 0 }

为解构设置默认值,当解构失败时使用默认值
move()使用了函数默认值{},然后解构,解构失败,使用解构默认值

function move({} = { x = 0, y = 0 }) {
    return [x, y]
}
move({ x: 3, y: 1 })    // { x: 3, y: 1 }
move({ x: 3})           // { x: 3, y: undefined }
move({})                // { x: undefined, y: undefined }
move()                  // { x: 0, y: 0 }

为函数设置默认值,仅当函数没有传参的时候才使用默认值
move({})传入了空对象,所以没有使用函数默认值{},接下来是解构,解构失败,由于没有解构默认值,其值为undefined

变量解构的用途

交换变量的值

[x, y] = [y, x]

从函数返回多个值

function example() {
    return [1, 2, 3]
}
var [a, b, c] = example()
function example() {
    return {
        foo: 1,
        bar: 2
    }
}
var { foo, bar } = example()

函数参数的定义

// 参数是一组有次序的值
function f([x, y, z]) {  ...  }
f([1, 2, 3])
// 参数是一组无次序值
function f({ x, y, z }) {  ...  }
f({ z: 1, y: 2, x: 3 })

提取JSON数据

var jsonData = {
    id: 1,
    is_error: false,
    result: [123, 456]
}
let { id, is_error, result } = jsonData

函数参数的默认值

jQuery.ajax = function(url, {
    async = true,
    beforeSend = function() {},
    cache = true,
    complete = function() {},
    corssDomain = false,
    global = true
    // ... more config
}) {
    // ... do stuff
}

遍历Map结构

任何部署了 Iterator接口的对象,都可以用 for...of 循环遍历

var map = new Map()
map.set('first', 'hello')
map.set('second', 'world')
for (let [key, value] of map) {
    console.log(key, value)
}
// first hello
// second world

输出模块的指定方法

const { SourceMapConsumer, SourceNode } = require("source-map")

相关文章

  • 解构赋值

    解构赋值:ES6 中新增了变量赋值的方式,从数组和对象中提取值,对变量进行赋值。 单独赋值给变量,解构赋值。 解构...

  • ES6笔记(解构赋值)

    ES6笔记(解构赋值) 解构赋值 变量的解构: 解构赋值允许指定默认值。 解构赋值必须保证赋值方 被赋值方类型一...

  • 变量的解构赋值

    数组的解构赋值: 解构,就是从数组和对象中提取值,然后对变量进行赋值 解构赋值: 解构不成功,变量的值就等于und...

  • ES6系列之变量的解构赋值

    本篇目录: 数组的解构赋值变量声明并赋值时的解构变量先声明后赋值时的解构不完全解构默认值交换变量解析一个从函数返回...

  • 解构赋值

    解构赋值 数组的解构赋值 嵌套,默认值,展开符 对象的解构赋值 对象解构赋值的本质与简写 对象解构的模式与变量 对...

  • 『ES6脚丫系列』变量的解构赋值

    『ES6脚丫系列』变量的解构赋值 第一章:变量的解构赋值的概念 【01】Q:什么是变量的解构赋值?有哪些方式? 吃...

  • ES6的解构赋值

    一、前言 什么是“解构赋值”呢?就是从数组或者对象中取值,对变量进行赋值,这就是变量的解构赋值。 二、数组的解构赋...

  • 名词

    1 解构: 从数组或对象中提取值,给变量赋值这被称为解构解构赋值的变量都会重新声明解构赋值的规则是,只要等号右边的...

  • 变量的解构赋值 - 字符串、数值、布尔值、函数参数

    一、字符串的解构赋值 二、数值和布尔值的解构赋值 三、函数参数的解构赋值 变量的解构赋值 - 数组篇[https:...

  • Z03_变量的解构赋值

    变量的解构赋值 数组的解构赋值 ES 中从数组和对象之中提取数值,对变量进行赋值,这个过程称为解构 1. 对于 S...

网友评论

      本文标题:变量的解构赋值

      本文链接:https://www.haomeiwen.com/subject/aagdextx.html