变量的解构赋值

变量的解构赋值

ES6允许我们通过数组或者对象的方式,对一组变量进行赋值,这就称为解构(等号两边的结构一定要相等这样才能拿到你需要的值)


在这里插入图片描述

字符串的解构赋值

JavaScript中字符串可以看成只读的数组,在字符串的结构赋值中有一个length属性可以获取该字符串长度

const [a, b, c, d, e] = 'hello';
// a = 'h', b = 'e'....

let {length : len} = 'hello'; // 该使用方法数组也合适
// len = 5
  • 数组的解析是适合Set结构的和Iterator接口的
    let [x, y, z] = new Set(['a', 'b', 'c']);
    // x = 'a', y = 'b', z = 'c'
    

回到顶部 目录

数组中的解构赋值

语法:let [a,b,c] = [1,2,3](把右边的值对应下表赋值给左边的变量)

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值

let [a, [b, c], d] = [1, [2, 3], 4];
// a = 1, b = 2, c = 3, d = 4

let [e, , f] = [1, 2, 3];
// e = 1, f = 3

let [g, ...h] = [1, 2, 3, 4];
// g = 1, h = [2,3,4]

解析问题

  • 如果变量对应没有值来解析,那么变量为undefined

    let [a] = [];
    // a = undefined
    
    let [b, c] = [1];
    // b = 1, c = undefined
    
    let [d, [e], f] = [1, [2, 3], 4];
    // d = 1, e = 2, f = 4
    
  • 等号两边的类型不同,解析时会报错

    // 报错
    let [foo] = 1;
    let [foo] = false;
    let [foo] = NaN;
    let [foo] = undefined;
    let [foo] = null;
    let [foo] = {};
    

默认值

解构赋值:当变量存在默认值,如果该变量对应的值为undefined,那么变量就被赋予默认值,否则就为对应值

ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效

let [a = true] = [];
// a = true

let [x, y = 'b'] = ['a']; 
// x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; 
// x='a', y='b'
  • 如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值
  • 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
function fn(){}
let [x = fn()] = [1];

let [x = 1, y = x] = [1, 2]; 
// x=1; y=2
let [x = y, y = 1] = [];     
// ReferenceError: y is not defined

回到顶部 目录

对象的解构赋值

语法:let { a, b } = { a: 'aaa', b: 'bbb' };(以变量与key对应赋值)

let obj = {
    a: 'aa',
    b: 'bb',
    c: 'cc'
}
let [a, b, c] = obj;

解析问题

  • 如果变量对应没有值来解析,那么变量为undefined

    let { c } = { a: 'aaa', b: 'bbb' };
    // c = undefined
    
  • 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者

    let { a: c } = { a: 'aaa', b: 'bbb' };
    // c = "aaa"
    // a = error: a is not defined
    

    就是把’aaa’的值赋值给c,a只是一个匹配模式,c才是真正的变量,这是针对这一种对象的解构赋值

  • 如果要将一个已经声明的变量用于解构赋值

    // 错误的写法
    let x;
    {x} = {x: 1};
    // SyntaxError: syntax error
    
    // 正确的写法
    let x;
    ({x} = {x: 1});
    

    由于let x;该语句以及结束,js解释器就会把{x}解析成代码块

默认值

var {x = 3} = {};
// x = 3

var {x = 3} = {x: undefined};
// x = 3

var {x = 3} = {x: null};
// x = null

属性的简写

  • ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
  • 简写的对象方法不能用作构造函数,会报错
    // 1.属性简写
    function fn(x, y){
        return{
            x: x,
            y: y
        }
    }
    // ==>
    function fn(x,y){
        return {x,y};
    }
    
    // 2.方法简写
    const obj1 = {
        fn : function(){
            return 0;
        }
    }
    // ==>
    const obj2 = {
        fn(){
            return 0;
        }
    }
    
    // 3.常用实例
    let ms = {};
    function getItem (key) {
    return key in ms ? ms[key] : null;
    }
    function setItem (key, value) {
    ms[key] = value;
    }
    function clear () {
    ms = {};
    }
    
    const exports1 = {
    getItem: getItem,
    setItem: setItem,
    clear: clear
    };
    // ==>
    const exports2 = { getItem, setItem, clear };
    
    // 4.简写的对象方法不能用作构造函数,会报错
    const obj3 = {
    f() {
        this.foo = 'bar';
    }
    };
    
    new obj3.f() // 报错
    

属性表达式

JavaScript定义属性的方式,在ES6之前只有一种方法

  • 直接用标识符作为属性名称(ES6以前)
  • 表达式作为属性名称(表示放在[]里面,新增加的一种方法)
    // 1. 用于属性
    let a = 'he';
    const obj1 = {
        [a] : true,
        ['a' + 'b']: 2
    }
    
    console.log(obj1[a]) // true
    console.log(obj1.ab) // 2
    console.log(obj1['ab']) // 2
    
    // 2. 用于方法名称
    const obj2 = {
        ['h'+'e'](){
            return '2';
        }
    }
    obj2.he() //"2"
    
    // 3. 注意属性名不能为对象
    const keyA = {a: 1};
    const keyB = {b: 2};
    
    const myObject = {
      [keyA]: 'valueA',
      [keyB]: 'valueB'
    };
    
    myObject // Object {[object Object]: "valueB"}
    // [keyA]和[keyB]得到的都是[object Object],所以[keyB]会把[keyA]覆盖掉,而myObject最后只有一个[object Object]属性,这就是","的操作
    
    • 属性名表达式与简洁表示法,不能同时使用,会报错const baz = { [foo] };
    • 属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object]

回到顶部 目录

函数参数的解构赋值

语法:[[1, 2], [3, 4]].map(([a, b]) => a + b); \\ [3, 7]

function fn({
    a,
    b,
    c = 10,
    d = 20,
} = {}){
    return a+b+c+d;
}

fn({a:1,b:2})
// 33

语法都是上面数组和对象的解构赋值

圆括号问题

尽量不要写带有()的语句出来
解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道,乱加圆括号也是导致编译报错

不能使用圆括号的情况:

  1. 变量声明语句 let [(a)] = [1]
  2. 函数参数 function fn([(z)]){}
  3. 赋值语句的模式 [({ p: a }), { x: c }] = [{}, {}];

可以使用圆括号的情况:

[(b)] = [3];
({ p: (d) } = {}); 
[(parseInt.prop)] = [3];

用途

  1. 交换变量的值 [a, b] = [b, a]
  2. 从函数返回多个值、提取json数据
    函数的返回值是一个对象的时候,我们可以用解构赋值来接受
  3. 函数参数的定义、函数参数的默认值(上面的函数参数的解构赋值)
  4. 其实就是来方便我们编写代码的

回到顶部 目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值