深圳做电商网站,陕西省建设工程施工许可证查询网站,郑州公司网站建设服务,项目营销策划方案什么是解构赋值
通过类似#xff08;或相同#xff09;的构型#xff0c;将已知数据的元素/属性解构并提取出来#xff0c;再赋值到相应变量#xff0c;可以是新建的变量#xff0c;也可以是已存在的变量/属性等#xff1b;最常见的是数组和对象的解构赋值#xff0c;…什么是解构赋值
通过类似或相同的构型将已知数据的元素/属性解构并提取出来再赋值到相应变量可以是新建的变量也可以是已存在的变量/属性等最常见的是数组和对象的解构赋值基本语法如下。
/* 绑定模式变量同用一个声明let/const */
/* 数组 */
const [a, b] array;
let [a, , b] array;
const [a aDefault, b] array;
let [a, b, ...rest] array;
const [a, , b, ...rest] array;
let [a, b, ...{ pop, push }] array;
const [a, b, ...[c, d]] array;
/* 对象 */
const { a, b } obj;
let { a: a1, b: b1 } obj;
const { a: a1 aDefault, b bDefault } obj;
let { a, b, ...rest } obj;
const { a: a1, b: b1, ...rest } obj;
let { [key]: a } obj;/* 赋值模式变量的声明各自独立 */
let a, b, a1, b1, c, d, rest;
let pop, push;
[a, b] array;
[a, , b] array;
[a aDefault, b] array;
[a, b, ...rest] array;
[a, , b, ...rest] array;
[a, b, ...{ pop, push }] array;
[a, b, ...[c, d]] array;({ a, b } obj); // 必须加上 ()
({ a: a1, b: b1 } obj);
({ a: a1 aDefault, b bDefault } obj);
({ a, b, ...rest } obj);
({ a: a1, b: b1, ...rest } obj);可以看到声明和解构赋值在同一语句的是绑定模式先声明再赋值的是赋值模式下面根据不同数据类型进行语法总结。 数组的解构赋值
将可迭代对象解构赋值给数组模式里对应位置上的变量。
基本语法
完全的模式匹配构型完全一致
let [a, b] [1, 2];
let [a, [b, c], [d], e] [1, [2, 3], [4], 5];数据更多只赋值指定位置
let [a, b] [1, 2, 3] // a1,b2
let [a, , b] [1, 2, 3, 4] // a1,b3,跳过第二个位置数据更少多余的变量赋值为 undefined
let [a, b, c] [1, 2] // cundefined
let [a, [b, c], d] [1, [2]] // cdundefined结合剩余参数将剩余的数据作为数组赋值给最后一个变量
let [a, ...rest] [1, 2, 3, 4] // rest [2, 3, 4]
let [a, , ...rest] [1, 2, 3, 4] // rest [3, 4]
let [a, [b, ...rest], c] [1, [2, ], 3, 4] // rest []带默认值的解构赋值
let [a1] [] // a1
let [a1] [undefined] // a1
let [a1] [null] // anull*将前面变量用作后面变量的默认值。
let [x, yx, z2*x] [1] // y1,z2
let [x, yx] [1, 10] // y10
let [xy, y] [1, 10] // 这种写法易错、且没有太多意义因为匹配是从左到右的扩展部分
一个数据交换的便捷语法 [b, a] [a, b]一般的可迭代对象Map、Set、String等都可以通过数组模式进行解构赋值*在函数参数列表中起提取相应参数的作用只有被提取的参数后续会被传入函数。
let [a, b] new Map([[1, 2], // a[1,2][3, 4], // b[3,4]
]);function* gen() {yield* [1, 2, 3]
}
let [x, y, z] gen() // x1,y2,z3function firstPlusThird([first, ,third]) { return first third; }
firstPlusThird([1, 2, 10, 20]) // 11注意事项
可以嵌套剩余参数必须在最后一个位置只有在没有匹配成功的时候才会执行默认值的表达式数组模式的右端的期待值是可迭代对象不要将可能匹配失败的变量作为默认值。
let [a, ...rest, b] [1, 2, 3, 4] // 报错剩余参数rest不能在中间
let [aconsole.log(1)] [1] // a1且不会执行console.log(1)
let [aconsole.log(1)] [] // aundefined且执行console.log(1)
let [xy,y] [] // 报错y没有匹配到就赋值给xx、y都没有声明成功
let [x, y] 1 // 报错
let [x] null // 报错对象的解构赋值
解构对象的属性给相同属性名的变量进行赋值和数组模式不同的是属性没有次序要根据属性名赋值。
基本语法
同名的属性匹配成功-属性值赋值给对应变量 / 没有同名的属性匹配失败-undefined
const employee {id: 42,isAdmin: true,salary: 1.8w,
};
let { id, isAdmin } employee; // id42,isAdmintrue
let { isAdmin, id } employee; // id42,isAdmintrue
let { wage } employee; // wageundefined将匹配到的属性赋值给其他名称的变量
/*
* : 后的才是变量名
* : 前的是要匹配的属性名
*/
let { id:ID } employee; // ID42,没有id这个变量
let { salary:wage } employee; // wage1.8w带有默认值
const employee2 { }
let { id1 } employee; // id42,匹配成功了
let { id1 } employee2; // id1,匹配失败了
let { id:ID1 } employee; // ID42,匹配成功了
let { id:ID1 } employee2; // ID1,匹配失败了嵌套
const o {done: false,materials: [ [copper,], { obsidian: 3kg, granite: 10t } ],rate: 0%,plus() { this.rate 1 this.rate.slice(0, -1) % }
}
let { materials: m } o; // m[ [copper,], { obsidian: 3kg, granite: 10t } ]
let { materials: [a, b] } o; // a[copper],b{ obsidian: 3kg, granite: 10t }
let { materials: [, { obsidian }] } // obsidian3kg带有计算属性。
let employee3 { id: 12,isAdmin: true
};
let x id
let { [x]: theId } employee3 // theId12扩展部分
数组/字符串等基本数据类型是特殊的对象有自己的属性length、0/1/…等索引甚至原型链上的方法都可以赋值尽管不能正常使用还有一些内置对象Math、Date 等一些好用的方法可以独立使用的方法都可以通过解构赋值的语法赋值给变量使得调用更方便*在函数参数列表中起提取相应参数的作用只有被提取的参数后续会被传入函数当解构一个对象时如果属性本身没有被访问它将沿着原型链继续查找如上面第1点。
let { 0:firstPos, 1:secondPos, length:len, at } [1, 2, 3, 4]
firstPos // 1
secondPos // 2
len // 4
at(0) // 报错因为没有指向的对象脱离了数组let { max, sin, PI:pi } Math
max(1, 4, 2)// 4
sin(pi/2) // 1let user { id: 32,name: Li Ming }, user2 {};
function getUserId({ id }) {return id;
}
getUserId(user) // 32
getUserId(user2) // undefined注意事项
将属性赋值给其他名字的变量时: 前的是属性名不是建立的变量也不会建立{} 可以没有变量null、undefined 不能解构的数据类型先声明再赋值的情况需要用 () 包围。先声明后赋值模式的语句 ()。
let { x:y } { x: 1 } // 将属性x 的值赋值给y创建了变量y没有创建变量x
let { a: 1 } null // 报错
let { } null // 报错
let { a: 1 } undefined // 报错
let { } undefined // 报错
let m;
{ m } { m: M } // 报错
({ m } { m: M }) // m1
({} { a: 1, b: 2 }) // 这样是允许的,尽管很怪字符串的解构赋值
字符串既可以作为类数组进行数组模式的解构赋值也可以作为对象进行对象的解构赋值。
let str Hello;
let strArr;
/* 作为数组被解构 */
let [a, b, , ,c] str; // aH,be,co
/* 作为对象被解构 */
let { length:n, 0:firstChar } // n5,firstCharH
({ 0:strArr[0], [str.length-1]:strArr[1] } str)
strArr // [H, o]函数参数的解构赋值
上面数组和对象的解构赋值扩展部分提到过。在参数列表中做解构的类型一般就是数组和对象模式
数组模式根据位置上匹配数据提取出来并进行指定传参对象模式根据属性名匹配到属性值提取出来并进行指定传参匹配失败传 undefined 。
let arr [1, 2, 10, 20], obj { value: 100 };
function getM([a, ,b], { value }) {return a b value ? a b: value; // 取大
}getM(arr, obj) // 100应用
简单地交换变量的值从函数返回多个值函数的解构参数提取 JSON 数据等等等等。
function f() { return [1, 2, 3] }let [a, b, c] f(); // a1,b2,c3