昨天学习了es6语法中解构赋值,解构赋值在声明中和函数传参提高了灵活性和便捷性,值得掌握该语法。
概念:
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
数组的解构:
let [a,b,c] = [1,2,3]; console.log(a); // 1 console.log(b); // 2 console.log(typeof c); // number console.log(a === 1); // true
ps:解构不成功,变量的值就等于undefined
let [arr,foo] = [1]; console.log(foo); // undefined
有两种解构:
1 完全解构,等号左边的变量和等号右边的值一一对应
2 不完全解构,等号左边的模式,只匹配一部分的等号右边的数组
let [x, y] = [1, 2, 3]; console.log(x); // 1 console.log(y); // 2 let [x,[a],y] = [1,[2,3],4]; console.log(a) // 2
数组解构赋值可以带有默认值
let [a,b=2] = [1]; console.log(a) // 1 console.log(b) // 2
解构赋值如果有默认值,与之对应的也有值,则覆盖默认值
let [a,b=2] = [1,3]; console.log(`a的值是${a} b的值是${b}` ) // 1 3
解构赋值中右边有undefined时,与之对应的左边会采用其默认值。若两者都是undefined,则为undefined
let [a,b=2] = [1,undefined]; console.log(`a的值是${a} b的值是${b}` ) // 1 2
ps:在es6的规定下,要判断两者是否相等,必须用三等===来判断。
let [a,b=2] = [1,null]; console.log(a) // 1 console.log(null === undefined) // false 严格模式下,null和undefined不等 console.log(b) // null
最常见的例子就是如何将两个数值互换,一般我们常用借用第三个变量或者用加减法来进行互换,因此数组的解构赋值也可以将两个数值互换。
let x = 1; let y = 2; [x, y] = [y, x]; console.log(`x:${x} y:${y}`) // x:2 y:1
对象的解构
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。如果对象解构赋值中没有找到对应的属性名,则返回undefined
let {b, a, c} = {a: 'peter', b: 'Bob'}; console.log(`a:${a} b:${b} c:${c}`) // peter Bob undefined
如果变量名和属性名不一致,根据对象解构的内部机制:先找到同名属性,然后再赋给对应的变量(我感觉既然是自己声明变量,倒不如向上面的一样就好)。
const obj = { foo: 'peter', bar: 25 }; let {foo: name, bar: age} = obj; console.log(`name:${name} age:${age}`) // name:peter age:25
对象解构赋值的默认值情况跟数组一样。
1 有默认值,与之对应的也有值,则覆盖默认值
2 右边有undefined时,与之对应的左边会采用其默认值。若两者都是undefined,则为undefined
3 右边的值是null,左边有默认值,也要返回null
ps: 当你解构对象并赋值给变量时,如果你已经声明或不打算声明这些变量(亦即赋值语句前没有let、const或var关键字),会报语法错误。
{obj} = {obj: 10} // Uncaught SyntaxError: Unexpected token =
这是因为JavaScript语法通知解析引擎将任何以{开始的语句解析为一个块语句(例如,{console}是一个合法块语句)。解决方案是将整个表达式用一对小括号包裹:
({obj} = {obj: 10})
在对象解构赋值中,最常用的就是,函数返回值,有多个时,可以按照返回对象的形式返回。
function foo() { return { foo: 1, bar: 2 }; } let { foo, bar } = foo();
可以提取 JSON 对象中的数据
let json = { id: 1, status: 200, data: [123, 456] }; let { id, status, data: number } = json; console.log(id, status, number); // 1, 200, [123, 456]
字符串解构
字符串解构赋值,是字符串被转换成了一个类似数组的对象
let [a,b,c,d,e,f] = 'hello'; console.log(`a:${a} b:${b} c:${c} d:${d} e:${e} f:${f}`) // a:h b:e c:l d:l e:o f:undefined console.log(typeof a) // string let [m,n,q,p] = 'w ord'; console.log(`m:${m} n:${n} q:${q} p:${p}`) // m:w n: q:o p:r let {length:len} = 'hello world'; console.log(len) // 12 let [a='H',b,c,d,e,f='W'] = 'hello'; console.log(`a:${a} b:${b} c:${c} d:${d} e:${e} f:${f}`) // a:h b:e c:l d:l e:o f:W
从上面的例子可知:
字符串是按着顺序依次赋值的,有空格也要赋值为空格。
左边的变量声明的个数>右边赋值的个数,那么从左往右的后面的元素赋值为undefined
左边的变量声明的个数<右边赋值的个数,那么右边多余的则不展示。
如果有类似数组的对象有length,可以对这个进行赋值。
有默认值的情况下,则会覆盖默认值,如果最后一个元素在赋值中为undefined则会使用默认值
函数参数的解构赋值
函数参数传参可以是数组,对象,以及字符串等等,按照以前的规定写,会出现冗杂,乱,通过解构赋值,可以解放了函数的传参。
function add([x, y]){ return x + y; } console.log(add([1,2])); // 3
函数参数的解构赋值可以带有默认值
function move({x = 0, y = 0} = {}) { return [x, y]; } console.log(move({x: 1, y: 2})); // [1, 2] console.log(move({x: 1})); // [1, 0] console.log(move({})); // [0, 0] console.log(move()); // [0, 0]
对应的笔记和实例,我放到了GitHub,https://github.com/sqh17/notes
有什么问题请私信或留下评论,一起加油。
参考资料:
阮一峰大大的es6标准入门:http://es6.ruanyifeng.com/