变量的解构赋值

数组解构赋值


基本用法
  • ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
  • 这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值
  • 如果解构不成功,变量的值就等于undefined
let [a, b, c] = [1, 2, 3]  // a=1, b=2, c=3

let [a, [b]] = [1, [4, 5]]   //  a=1, b=4 (5在这里不会进行赋值)

let[a, b, ...c] = [1, 2, 3, 4, 5]  // a=1, b=2, c=[3, 4, 5]

let[a, b, c] = [1, 2]    // a=1, b=2, c=undefined

以上都是数组解构赋值的例子,提一下'...c'。它的意思是 c 在一定条件下可以被赋值为数组,如上,c被赋值为 [3, 4, 5] => 在 a, b 赋值完后,后面的所有值都会被 c 接纳。


如果等号的右边不是数组则会报错,一下的赋值都是不成功的。

let [a] = 1;
let [a] = false;
let [a] = NaN;
let [a] = undefined;
let [a] = null;
let [a] = {};

默认值
let [x, y = 'b'] = ['a']   // x='a', y='b'
let [x, y=4] = [10, undefined]  //  x=10, y=4
let [x, y=4] = [10, null]      //    x=10, y=null
  • 虽然只是一个单词之差,但是结果却截然不同。 => ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效
function fn() {
  console.log('javascript');
}
let [x = fn()] = [1];
// 如果默认值是表达式的话,只有在用到的时候,才会求值。
// x的默认值为fn(),但是数组中的 1 不严格等于 undefined, 所以 x 会被赋值为 1

  • 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
let [x = 1, y = x] = [];     // x=1; y=1
let [x = y, y = 1] = [];     // ReferenceError: y is not defined
// 由于在 y 还没有声明之前就将 y 的值赋给 x,所以会报错


对象解构赋值


基本用法
  • 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
  • 如果变量没有对应的同名属性,导致取不到值,最后等于undefined
let{a, b} = {a:'right',b:"left"};// a='right', b:'left'

let {a} = { been: 'aaa', chest: 'bbb' };   //  a=undefined
  • 下面代码中其实存在一个赋值机制,他会先在对象中找到同名属性 a, 然后再给 a属性的变量 b 进行赋值,所以最终 b=1而不是 2,两个对象是分离开来的。
let { a: b } = { a: 1, b: 2 };  // b=1

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;     // f='hello'  l='world'
  • 解构也可以用于嵌套结构的对象,需要注意的是,对应的结构和属性一定要匹配才赋值。
let lesson = {
    plat:{
        name:'Jack',
        age : 18
    }
}
let {plat:{name, age}} = lesson
console.log(name,age)   // name='Jack', age=18
  • 下面是比较复杂的结构,需要注意的是 loc:start:都指的是模式,他们是不会被赋值的,只有模式下的变量才会被赋值。
const node = {
  loc: {
    start: {
      line: 1,
      column: 5
    }
  }
};
let { loc, loc: { start }, loc: { start: { line }} } = node;

默认值
let {x, y=4} = {x:10, y:undefined}  //  x=10, y=4
let {x, y=4} = {x:10, y:null}      //   x=10, y=null

和数组结构类似,对象成员必须严格等于 'undefined'才会允许默认值进行赋值,否则会以对象成员该值进行赋值。


函数参数的解构赋值

function fn([a,b] = [1,2]){
    console.log([a, b])   
}

fn([2]) // => [2, undefined]
-----------------------------
function fn([a,...b] = [1,2]){
    console.log([a, b])   
}

fn([2]) // => [2, Array(0)]
-------------------------------
function fn2([a=0, b=3] = []){
    console.log([a, b])
}
fn2()  // => [0, 3]

注意以上的三种写法:

共同点:

  • 传参的位置都为等号后面,即 [1, 2],[] ,参数会对这些进行替代,不穿则默认为这些。

不同点:

  • 第一和第二种是为函数的参数 a, b进行数组解构赋值,解构失败的话返回 undefined,不传的话默认就为 [1, 2],然后再对 [a, b] 进行解析
  • 第三种表示函数的变量是一个数组,通过对数组解构对数组的变量 a, b进行赋值,
    如果解构失败,a 和 b等于默认值,即不传或者穿 {} 的保持默认值为 [a=0, b=0]

圆括号的使用

// 错误的写法
let x;
{x} = {x: 1};
// 正确的写法
let x;
({x} = {x: 1});
  • JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
// 全部报错
let [(a)] = [1];

let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};

let { o: ({ p: p }) } = { o: { p: 2 } };
// 报错
function f([(a)])
// 报错
function f([z,(a)])
  • 上面 8个语句都会报错,因为它们都是变量声明语句,模式不能使用圆括号。
let {c:name} = ({c:'Jack'})  // 是声明语句中可以用圆括号的例外
({c:(name)} =({c:'Ben'}))  //正确 => 多重括号的使用
[(b)] = [3]; // 正确
({ p: a }) = { p: 42 };  //错误
({ p: (a) } = {p: 42}); // 正确
  • 在非声明语句使用,也是就是赋值语句,其次模式 p:是不能够添加括号的
  • 其实我们只需要记住,在变量声明的时候,变量不能够跟括号,赋值的对象或者数组添不添加括号不影响全局
  • 其次,在赋值语句中,必须对整体添加括号,不然解析器会识别不了

应用

//最广泛的用途是函数返回多个参数
function pop(){
    let a, b, c;
    a = 1;
    b = a + 1;
    c = a*b;

    return([a, b, c])
}
// 这样就解决了之前我们函数只有一个返回值的弊端
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值