解构就是ES6容许按照必定模式,从数组和对象中提取值,对变量进行赋值(只能用于数组,对象或迭代器)。若是解构不成功,则等于undefined,但不能赋值为undefined和null,由于undefined和null不属于数组或对象数组
数组的解构赋值就是,按照数组元素的次序,取出它位置所对应的值,具体以下函数
var [a, b, c] = [1, 2, 3]; // a=1;b=2;c=3 至关于var a=1, b=2, c=3; // 也能够用于let,const声明变量 let [x, y] = [4, 5] // x=4, y=5 // 位置对应 var [, , c] = [1, 2, 3]; // c=3 var [a, b, c] = [, 2,]; // a=undefined; b=2; c=undefined // 嵌套数组 位置对应 var [a, [[b], c]] = [1, [[2], 3]]; // a=1; b=2; c=3 // ...表示剩下的全部值组成数组 var [a, ...b] = [1, 2, 3, 4];// a=1; b=[2,3,4]; var [a, ...b, c] = [1, 2, 3, 4]; //报错 Uncaught SyntaxError: Rest element must be last element in array var [a, ...b] = [1]; // a=1; b=[];
解构只能用于数组,对象或迭代器,重要的事再重复一遍
固然,解构赋值也容许指定默认值code
var [a=1] = []; // a=1 var [a, b=2] = [1]; // a=1, b=2 var [a, b=2] = [1, undefined]; // a=1; b=2 var [a, b=2] = [1, null]; // a=1; b=null;
思考一下,下面输出的结果,let声明时为何报错对象
var [x=y,y=1]=[]; // x=undefined; y=1 let [x=y,y=1]=[]; // 报错 Uncaught ReferenceError: y is not defined
上面提到了,数组的解构赋值是按照元素的位置来取值的,而对象的解构赋值是按照属性名来取值的
具体请看下面的例子token
// 属性名和变量名一致 var {a, b} = {a:"aa", b:"bb"}; // a="aa"; b="bb" var {a, b} = {b:"bb"}; // a=undefined; b="bb" 变量名a由于找不到属性名a的值 // 属性名与变量名不一致 var {a:c, b:d} = {a: "aa", b:"bb", c:"cc", d:"dd"}; //c="aa"; d="bb" 属性名为a,变量名为c //对象嵌套数组 var o = { p: ["hello", {y: "world"}] }; // 也支持let和const let {p:[x, {y}]} = o;// x="hello"; y="world"; 注意:p为属性名而不是变量名 // 对象嵌套对象 var o = { p: { q: { x: "hello", y: "world" } } }; var {p:{q:{x, y}}} = o; // x="hello"; y="world"; 注意p,q为属性名而不是变量名
为已经声明的变量进行解构赋值,必须把整个表达式用小括号包裹,不然会报错,报错缘由就是由于JavaScript语法通知解析引擎将任何以{开始的语句解析为一个块语句(例如,{console}是一个合法块语句)ip
var x; {x} = {x:1}; // 报错 Uncaught SyntaxError: Unexpected token = ({x} = {x:1}); // x=1 let obj = {}; let arr = []; ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true }); // obj={prop: 123}; arr=[true]; 注意区别属性名和变量名,foo,bar是属性名 obj.prop,arr[0]是变量名
变换变量的值element
var a = 1; var b = 2; [a, b] = [b, a]; // a=2; b=1;
函数取值io
function func1(){ return [1, 2, 3]; } var [a, b, c] = func1(); // a=1;b=2;c=3; function func2(){ return { a: "a", b: "b" } } var {a, b} = func2(); // a="a";b="b"
函数参数的定义及设置默认值console
function func3({x, y, z}){ console.log(x+' '+y+' '+z); } func3({x:"x",y:"y",z:"z"});//x y z function func4({x=1, y=2, z=3}){ console.log(x+' '+y+' '+z); } func4({});// 1 2 3
遍历Map结构ast
var map = new Map(); map.set('x','xx'); map.set('y','yy'); //获取键名和键值 for(let [key, value] of map){ console.log('key='+key+' value='+value); //key=x value=xx //key=y value=yy } //获取键名 for(let[key] of map){ console.log("key="+key); // key=x // key=y } // 获取键值 for(let[, value] of map){ console.log("value="+value); // value=xx // value=yy }
为何func5和func6的结果不同,请注意为变量赋值和为函数的参数指定默认值
function func5({x=0, y=0}={}){ console.log([x,y]); } func5({x:3, y:8}); // [3, 8] func5({x:3}); // [3, 0] func5({}); // [0, 0] func5(); // [0, 0] function func6({ x, y } = { x: 0, y: 0 }){ console.log([x, y]); } func6({x:3, y:8}); // [3, 8]; func6({x:3}); // [3, undefined] func6({}); // [undefined, undefined] func6(); // [0, 0]