1.数组的解构赋值
数组的解构赋值其实是=左右进行“模式匹配”。
let [a,[b],c] = [1,[2],3]; // a=1;b=2;c=3
let [a, ...tail] = [1,2,3,4,5]; // a = 1, tail = [2,3,4,5]
let [a,b,c] = [1]; // a=1 b=undefined c=undefined
知识兔=有侧不能是非数组,非数组会自动转为包装对象。{}不行,因为对象不含iterator接口。但是Set可以,Set有iterator接口。
let [a,b,c] = new Set([1,2,3]) // a=1, b= 2, c= 3
知识兔只要数据结构有iterator接口就可以使用数组结构。用Generator函数生成的iterator对象也可以解构。
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
};
const a = fibs();
a.next();// { value: 0, done: false } // a=1,b=1
a.next();// { value: 1, done: false } // a=1,b=2
a.next();// { value: 1, done: false } // a=2,b=3
a.next();// { value: 2, done: false } // a=3,b=5
a.next();// { value: 3, done: false }
a.next();// { value: 5, done: false }
let [first,second,third,four,five,six] = fibs();
console.log(first,second,third,four,five,six) // 0,1,1,2,3,5
知识兔数组解构允许设置默认值,=右侧的值为undefined时,左侧使用默认值
let [a=5,b=6, c=7] = [undefined,null,];
// a = 5, b=null, c=7
知识兔2.对象的解构赋值
对象的解构赋值其实本质上也是“模式匹配”。
let {foo, bar} = { foo: 'aaa', bar: 'bbb' }
知识兔因为对象可以简写,其实应该是下面的形式
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
知识兔解构赋值的变量其实是:后面的变量名,:前端的值相当于匹配的模式
let { hello: h, world: w } = { hello: 'hello', world: 'world'}
// h='hello' w = 'world'
知识兔对于嵌套解构
let obj = {
web: {
js: {
nodejs: 'node',
reactjs: 'react'
}
}
}
const { web, web: {js}, web: {js: {nodejs, reactjs}}} = obj;
// web= { js: { nodejs: 'node', reactjs: 'react' } }
// js = { nodejs: 'node', reactjs: 'react' }
// nodejs = 'node'
// reactjs = 'react'
知识兔解构可以取到继承的原型对象上的属性
let obj1 = {};
let obj2 = { a: 1 };
Object.setPrototypeOf(obj1, obj2)
obj1.a; //1
知识兔对象解构允许设置默认值
let { x: y = 1, z = 5, k: m=8} = { x:5, z:6 }
// y=5, z=6, m=8
知识兔⚠️1)先声明,再解构的情况
let x;
({x} = {}) // 必须有小括号,否则js引擎将{x}作为代码块处理
// x = undefined
知识兔2)数组是特殊对象,允许对数组进行对象解构赋值
const arr = [1,4,2,3];
let {0: first, [arr.length-1]: last, length} = arr;
console.log(first,last,length) // 1,3,4
知识兔3. 字符串解构赋值
对字符串使用解构赋值时,js引擎将字符串转为类数组对象String(),类数组都有length属性
let str = 'hello';
let [a,b,c,d,e] = str;// 数组解构 'h' 'e' 'l' 'l' 'o'
let { length } = str; // 对象解构 5
知识兔4. 数值和布尔值解构赋值
数值和布尔值进行赋值操作时,右侧的数值和布尔值会自动转为包装对象Number(),Boolean()
let { toString: s } = 124;
//s === Number.prototype.toString
知识兔5.函数参数解构赋值
函数参数的解构赋值类似数组,对象的解构赋值
[[1, 2], [3, 4]].map(([a, b]) => a + b);
知识兔对于参数的对象解构,注意默认值的赋值位置
function move1({a=0,b=0} = {}) { // 相当于给参数a,b赋初值
return [a,b]
}
function move2({a,b} = {a:0, b:0}) { // 相当于默认传参a = 0, b= 0,即不传参时的默认值
return [a,b]
}
console.log(move1()); // [0,0]
console.log(move2()); // [0,0]
console.log(move1({}));// [0,0]
console.log(move2({}));// [undefined,undefined]
console.log(move1({a: 3})); // [3,0]
console.log(move2({a: 3})); // [3,undefined]
知识兔6.小括号的使用
避免使用小括号。(