03.变量的结构赋值

    科技2022-07-15  151

    1.数组的解构赋值

    基本用法:

    ES6允许按照一定模式从对象和数组中提取值,然后对变量进行赋值,称为解构;数组解构赋值本质上是一种模式匹配,只要等号两边的模式相同,左边的变量就会被赋予对应的值; <script> let [a,b,c] = [1,2,3]; console.log(a,b,c); // 1 2 3 // 只要等号两边的模式匹配,就能完成解构赋值 let [, , third] = ["aa","bb","cc"]; console.log(third);// cc let [one,[two,[three]]] = [1,[2,[3]]]; console.log(one,two,three); </script> 如果解构不成功,变量的值为undefined;不完全解构:等号左边的模式只能匹配一部分等号右边的数组,此时依然能够解构成功; // 不完全解构 let [aaa,bbb] = [111,222,333]; console.log(aaa,bbb); // 111 222 如果等号右边不是数组(严格来说是不可遍历的结构),将会报错,如1、false、NaN、null、undefined、{},这些值转换为对象以后不具备Iterator接口(前5个),或者本身就不具备遍历器(最后一个);结合上一条,也可以认为只要是具有Iterator接口的数据结构,都可以采用数组形式解构赋值;

    默认值:

    解构赋值允许设置默认值:在等号右边能匹配到值的前提下,默认值无效; // 解构赋值的默认值设置 let [d = 1] = []; console.log(d);// 1 let [x = 1] = [undefined]; x // 1 let [x = 1] = [null];// null 不全等与undefined x // null ES6内部用全等判断一个位置是否有效,因此如果一个数组成员如果不是全等于undefined,默认值是无效的;如果一个默认值是一个表达式,那么该表达式是惰性求值的,即只有在用到默认值时才会求值; //默认值为表达式时,表达式只有在用到时才会求值 let [a = fn()] = []; let [b = fn()] = [222]; function fn(){ return 1; } console.log(a,b); // 1 222 默认值还可以是等于一个其他变量,前提是该变量必须已经声明; // 默认值也可以是其他变量(该变量需要已经被声明) let [x = 1 , y = x] = []; console.log(x,y);// 1 1 let [w = z , z = 1] = [] console.log(w); // 报错,z还未声明

    2.对象的解构赋值

    对象解构与数组解构有一个重要不同:数组中的元素是按次序排列的(变量取值由位置决定),但是对象的属性是无序的,要赋值的变量需要跟属性同名才能取到正确的值;对象解构赋值的内部机制是先找到同名属性,然后再赋值给相应地变量,真正被赋值的是后者;常见的两种情况: 变量名等于对象中的属性名;变量名不等于对象中的属性名; // 1.变量名等于属性名: let { a , b } = {a :1 , b : 2}; console.log(a,b); // 1 2 // 2.变量名 !== 属性名 let{first : f , last : l} = {first : 3 , last : 4}; console.log(f,l); // 3 4 与数组一样,对象解构也可以嵌套使用; // 可以嵌套使用 let obj = { p : [ "hello", { y : "world"} ] } let { p : [x,{y}]} = obj; console.log(x + y); // helloworld 可以设置默认值,生效的前提是对象的属性值严格等于undefined; // 可以使用默认值,默认值生效的前提是对象的属性全等于undefined let {q,w = 1} = {q : 11 , w : undefined}; console.log(q,w); // 11 1 w严格等于undefined,因此默认值等于1 解构赋值允许左边的模式之中不放置任何变量名;对象解构可以很方便的将现有对象的某个方法赋值给变量; // 对象解构可以很方便的将现有对象的某个方法赋值给变量 let {random,floor} = Math; console.log(random);// ƒ random() { [native code] } 数组本质是特殊的对象,因此可以对数组进行对象属性的解构; // 数组本质是特殊的对象,因此可以对数组进行对象属性的解构 const arr = [1,2,3,4,5,6]; let {0 : first , [arr.length - 1] : last} = arr; console.log(first,last);// 1 6

    3.字符串的解构赋值

    字符串也可以解构赋值,此时字符串被转换成一个类似数组的对象(伪数组); const str = "hello"; let [a,b,c,d,e] = str; // 此时该字符串被转化成一个伪数组,具有length属性但是没有数组的方法 console.log(a,b,c,d,e); // h e l l o

    4.数值和布尔值的解构赋值

    在使用数值和布尔值进行解构赋值时,数值(==>Number)和布尔值(==>Boolean)会先转换成对象;解构赋值的规则是:只要等号右边的值不是数组或对象,会先将其转换成对象;undefined和null无法转换成对象,所以不能对他们进行解构赋值; // 数值和布尔值,会先被转换成对象再进行赋值 let {toString : s} = 1; let {toString : b} = true; // 判断s和b的toString的值是否等于对象的toString方法 console.log(s === Number.prototype.toString); // true console.log(b === Boolean.prototype.toString); // true

    5.函数参数的解构赋值

    函数参数也能使用解构赋值;函数参数解构能使用默认值(同样,undefined值能触发默认值); // 函数参数使用解构赋值 function add([x,y]) { console.log(x + y); } add([1,2]); // 3 let res = [[1,2],[3,4]].map(([a,b]) => a + b); // map遍历数组,并返回回调函数处理结果组成的新数组 console.log(res);//[3,7] // 可以使用默认值 function move({x = 0,y = 0}) { return [x,y]; } let res1 = move({x : 1 , y : 2}); let res2 = move({x : 1 }); let res3 = move({}); console.log(res1); // [1, 2] console.log(res2); // [1, 0] console.log(res3); // [0,0]

    6.圆括号问题

    对于编译器而言,如何分别一个式子是表达式还是模式,没有办法在一开始就对此作出判断,只有在解析到(或解析不到)等号时才能确定;因此,只要有可能引起解构歧义,就不要使用圆括号;建议:只要有可能,就不要在模式中使用圆括号;简单来说,只要是将模式放到圆括号中,都是非法的;

    不能使用圆括号的情况:

    变量声明语句: // 1.变量声明语句不能使用圆括号 let [(a)] = 1; let {(a) : 1} = {}; 函数参数(也属于变量声明): // 2.函数参数 function test([(a)]) { // 哈哈哈哈哈 } 赋值语句的模式: // 3.赋值语句中的模式 ({ p : a })= { p :44};

    可以使用圆括号的情况:

    赋值语句的非模式部分可以使用圆括号: // 赋值语句的非模式部分可以使用圆括号 [(a)] = [3]; console.log(a); // 3 ({p : (b)} = {p : 4}); console.log(b);// 4

    7.用途

    交换变量的值: // 1. 交换变量值 let a = 1; let b = 2; [a,b] = [b,a]; console.log(a,b); // 2 1 从函数返回多个值: // 2. 从函数返回多个值,以数组为例(对象也同理) function test() { return [1,2,3]; } let [c,d,e] = test(); console.log(c,d,e); // 1 2 3 定义函数参数: // 3.定义函数参数 // 3.1 函数参数为有次序的值时,使用数组解构赋值 function fn1([g,h]) { console.log(g,h); } fn1([1,2]); // 1 2 // 3.1 函数参数为无次序的值时,使用对象解构赋值 function fn2({one : name , two : age}) { console.log(name,age); } fn2({one : "peanut",two : 88}); // peanut 88 提取JSON数据: // 4. 提取json数据 let jsonData = { name : "peanut", age : 33, learning : ['javascript','less'] } // 数组解构赋值 let {name,age,learning : subject} = jsonData; console.log(name,age,subject);

    设置函数参数默认值: 比如设置jQuery中ajax方法的参数默认值;

    遍历map结构

    // 5.遍历Map结构 // 5.1 获取对象的键 值 let map = new Map(); // 设置map对象的属性 map.set("first","peanut"); map.set("second","test"); for(let [key,value] of map) { console.log(key + " " + value); } // first peanut // second test // 只获取键 for(let [key] of map){ console.log(key); } // first // second // 只获取值 for(let [,value] of map){ console.log(value); } // peanut // test 输入模块指定的方法 // 输入模块的指定方法 const { SourceMapConsumer, SourceNode } = require("source-map");
    Processed: 0.023, SQL: 8