五十四.解构赋值

286 阅读4分钟

概述

1.解构赋值是对赋值运算符的扩展。

优点:在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

2.是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。

解构赋值核心是声明标识符(变量)按照某种数据模型(js中只有数组和对象)解析(即取出数据模型的成员值)并赋值给声明的标识符(变量)。数组形式解构赋值 需要按照对应位置。对象的解构赋值是与变量名有关,变量标识符必须与对象成员同名,才能取到正确的值。

数组和对象的数据模型:数组中括号[],对象大括号{}。

数组和对象取成员的用法(解析):数组取元素中括号[]加下标,对象取成员点语法。

解构模型

在解构中,解构的源就是传入的对象和数组,解构赋值表达式的右边部分。解构的目标就是被赋值的变量,解构赋值表达式的左边部分。

image.png

image.png

image.png

image.png

报错的原因:解析错误,obj3.x1取出的是undefined,undefined和null是基本数据无法包装对象不能保存数据也不能调点语法取成员。解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错。解构赋值时,如果等号右边是数值和布尔值,则会先包装对象。

image.png

image.png

image.png

解构的目标(标识符)在数组中相当于占位符,这个标识符用于保存解构源的数组中对应下标的数据,而对象中的标识符就是对象的成员名,解构源的对象中有这个成员且成员名和解构目标的标识符一样。如果对象的成员名和标识符不一致,则是undefined,表示该标识符取出对象不存在的成员会取对象原型链上的成员,原型链上也没有就会取出undefined。

解构默认值

解构赋值不成功的变量的值等于undefined,即不完全解构。

   let [a, b] = [1]; // a = 1, b = undefined
        //隐式操作:let a=[][0] let b=[][1]
        let obj = { p: [{ y: 'world' }] };
        let { p: [{ y }, x] } = obj; // x = undefined y = 'world'
        //隐式操作:let p=obj.p  let y=p[0].y   let x=p[1]
        console.log(a,b,666);
        console.log(x,y,777);

image.png

当不想从解构源中解构出的值为undefined,解构赋值允许指定默认值。

let arr=[{age:20},{name1:"karen"}]
		let [{age,name1="jack"}]=arr
		//隐式操作:let name1=jack name1=arr[0].name1
        //先将默认值赋值给该变量标识符,再取出对应的解构源中的数据赋值给变量标识符
        let [a = 6, b=7] = []; 
		console.log(age,name1);
        console.log(a,b);

image.png

默认值不一定为字面量,也可以引用解构赋值的其他变量,但该变量必须已声明。

let [x = 1, y = x] = [];     // x=1; y=1
        let sample30 = 31;
        let { sample31 = sample30, sample32 = 3 } = {};
        console.log(x,y,666);
        console.log(sample31, sample32,777); // 31, 3

image.png

ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个解构源中的成员严格等于undefined,默认值才会生效。即使该解构源中有成员保存了undefined作为值也会让默认值生效但null不会让默认值生效。

let arr=[{age:26,name1:"jzx"},{name1:"gem"}]
        let [{age,name1="phm"}]=arr
        let [a = 6, b=7] = [null,undefined]; 
        console.log(age,name1,777);
        console.log(a,b,666);

image.png

函数参数也可以解构赋值

image.png

image.png

image.png

image.png

字符串的解构赋值

字符串也可以解构赋值。当字符串进行解构赋值的时候,字符串被转换成了一个类数组。类数组也有length属性,所以可以通过这个方式获取字符串的长度。

  let str = "jzxphmgem";
        let { length } = str;
        let [a, b, c, d, e] = 'hello';
        console.log(length,666);//9
        console.log(a, b, c, d, e,777); //h e l l o

image.png

对数组进行对象属性的解构

由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

 let { 0: sample0, 1: sample1 } = [1, 2];
        //隐式操作:let simple0=arr[0]   let simple1=arr[1]
        console.log(sample0, sample1);

image.png

解构赋值的使用场景

不用临时变量,交换两个变量的值

  let a=6;
  let b=7;
  [b,a]=[a,b]
  console.log(a,b);

image.png

函数多个返回值的解构赋值

function useState(num){
            function fn(arg){
               //让外界的count变量改变为arg
            };
            return [num,fn];
        };
        var [count,setCount]=useState(0);//说明该函数需要返回一个数组作为解析源
        //隐式操作var count=[][0];  var setCount=[][1];
        console.log(count);//0
        setCount(2000);
        console.log(count);//2000

提取JSON数据

可以使用解构赋值一次性提取多个数据

 let jsonData = {
            id: 7,
            status: false,
            data: [{ name: 'jzx' }, { name: 'phm' }, { name: 'gem' }]
        };
        let { id, status, data } = jsonData;
        console.log(id, status, data);
        // 7, false, [{ name: 'jzx' }, { name: 'phm' },{ name: 'gem' }]

image.png

解构赋值声明变量的注意点

//解构声明变量是声明解构的最小单位
        let obj={name:"jzx",age:26,music:{music_name:["an"]}};
        let {name,music:{music_name}}=obj;
        console.log(name);
        console.log(music_name);
        console.log(music);

image.png

解构时声明的变量是声明解构的最小单位,所以是声明的music_name