首先是数组的解构赋值
1.这是等号左右类型一样的情况下 数组的元素是按次序排列的,变量的取值由它的位置决定 如下:
let [,,b] = [1,2,45]
console.log(b) // 45
let [a,,c]= [1,2,3]
console.log(a,c) // 1 3
let [d] = []
console.log(d) // undefined\
let [e,f] = [1]
console.log(e,f) // 1 undefined
let arr = [1,[2,3],4]
let [a,b,c] =arr;
console.log(a,b,c) // 1 [2,3] 4
2.等号左右类型不一样的情况下
let [g] = 1
let [g] =0
let [g] =false
let [g] =undefiend // undefined is not defined
let [g] = NaN
let [g] =null
let [g] = {}
console.log(g)// 1 0 false NaN null {} is not iterable 1是不可迭代的 就是它转为对象后或者本身没有iterable接口所以解构时后报错
3.等号左右一样但是左右参数个数不一样的情况下 右边多了就不用管 左边多了 多出的值就是undefined 当然左边也可以设置默认的值 这样当右边对应的没有值时(或者为undefined)也不至于成为undefined 它内部使用严格的=== 来判断是否有值 来决定是否使用默认值
let [a='nihao',b] = [,'wanghongting']// console.log(a,b) // nihao wanghongting
let [a,b='wht'] = ['nihao',undefined] // console.log(a,b) // nihao wht
let [a,b='wht'] = ['nihao','undefined'] ;console.log(a,b) // nihao undefined 需要注意的是上面的和下面的不一样的原因是 上面告诉我们右边第二个数据是undeined类型的 说明没有定义 而这个是字符‘undefined’
let [a,b='wht',c,d,e] = ['nihao',null,Number,Boolean,String] ;console.log(a,b,c,d,e) // nihao null ƒ Number() { [native code] } ƒ Boolean() { [native code] } ƒ String() { [native code] } 如果是number string boolean 就会报错 说它们undefined因为 数组中除了数值,其它基本类型要加引号 就是字符
function fn(){
console.log('nihao')
}
let [a = fn()] = [1];
console.log(a) // 1 因为右边对应的有值 所以不用使用默认值 fn就不用执行 如果右边里面对应的是undefined 那就会执行fn()
let [a = fn()] = [undefined]
console.log(a) // nihao undefined 因为这个函数并没有返回值
4. 默认值可以引用解构复制的其他变量,但是该变量必须已经声明过了
let [x=2,y=x] = []; console.log(x,y) // 2 2
let [x=2,y=x] = [10]; console.log(x,y) // 10 10 之所以等于10是因为解构赋值右边有定义的值
let [x = 1,y = x] = [10,11]; console.log(x,y) // 10 11 说明赋值比默认值优先级高 如果右边有对应的就按对应的 如果没有就默认值
let [x=y,y=1] = [1,2]; console.log(x,y) // 1,2 不报错 是因为右边赋值给它了 不需要应用其他变量了用不到默认值
let [x=y,y=1] = []; console.log(x,y) // 报错 Cannot access 'y' before initialization 初始化之前找不到y 也就是上面说的可以引用其他变量 但必须先声明
let [x=y,y=1] = [1]; console.log(x,y) // 1 1
let [x=y,y=1] = [,2]; console.log(x,y) // 报错 Cannot access 'y' before initialization
5.Set 这种数据结构 也可以用数组的解构赋值
let [a,b,c] = new Set(['a1','b11','c1'])
console.log(a,b,c) //a1 b11 c1
// generator 函数 也具有这个iterable接口 以后再说
对象的解构赋值
1. 对象的属性没有次序,变量必须与属性同名,才能取到正确的值 当然下面也有解决办法 在下面3中有提到
let {age,name} = {name:'wht',age:20,like:'eat'}
//console.log(age,name) // 20 'wht' // 不像数组的解构赋值次序要一一对应 对象不用的 只要等号左右有同名属性就可以取到右边的值
let {sex} = { name:'wht',age:20,like:'eat'} // 等号左右属性名不相同 取不到值 属于解构失败 就是undefined
//console.log(sex) // undefined
2. 可以很方便的将现有对象的方法赋值到某个变量
let {log, sin, cos,random,abs} = Math ;//console.log(abs(-12)) // 12 等同于
Math.abs(-12)
let {log,warn} = console
log('nihao') // 打印的是nihao
warn('jinggao') // 打印的是⚠️jinggao 警告
3. 变量名与属性名不一致 可以这样做到解构赋值 等于重新赋值
let {sex: nv} = {sex:'女',name:'wht'}
console.log(nv) // 女
let obj = {named:'王婷婷',like:'eat'}
let {named:names,like:likes} = obj
//console.log(named,names) // 报错 named is not defined
console.log(names,likes) // 打印的结果是 王婷婷 eat 也就是说解构赋值完毕 左边的属
性又把取到的值赋值给了新的变量 虽然named匹配到了 但是被赋值的是变量names
4. 对象的嵌套解构赋值
let obj = {
p: ['hello',{name:'王梦琪'}]
}
//let {p:[x,{name}]} = obj;console.log(x,name) // 此时不能打印p 因为它已经赋值给后面的变量了 打印的结果 hello 王梦琪
let {p,p:[x,{name}]} = obj; console.log(p,name,x) // ['hello',{name:'王梦琪'}] '王梦琪' 'hello' 第二个p是一个模式 类似上面的赋值给变量的角色
let node = {
loc: {
start: {
line: 1,
column: 2
}
}
}
let { loc, loc: { start }, loc: { start: { line, column } } } = node
console.log(loc, start, line, column) // {line: 1, column: 2}column: 2line: 1__proto__: Object 1 2
let obj = {};
let arr = [];
({ a: obj.names, b: arr[0] } = { a: '轩', b: 0 }) // 用()抱起来是避免发生语法的错误
console.log(obj, arr) // {names:'轩'} [0]
5 对象的默认赋值
let {x=2} = {} // console.log(x) // 2
let {x,y=5} = {x:1}// console.log(x,5) //1 5
let {x:y=5} = {x:1,y:9}
console.log(y)
// 默认值生效的条件是 对象的属性值严格等于undefined
var {x=3} = {} //和var {x=3} = {x} // 没有定义就是等于undfined
//console.log(x) 3
var {x=3} = {x:null};// console.log(x) // null
var {x=3} = {x:''} ;//console.log(x) // 打印台是空