# 2、变量的解构赋值
从数组和对象中提取值,对变量进行赋值,这被称为解构
# 1、数组的解构赋值
变量赋值
// before let a = 1; let b =2; let c = 3; // Es6 let [a,b,c] = [1,2,3]; // 不完全解构 let [x,y] = [1,2,3,4] // x = 1 ; y =2; // 解构不到的undefined let [n,m] = [1] // n =1 ; m = undefined; // 左右结构不一致会报错, 因为转化为对象没有Iterator接口 let [foo] = null; let [foo] = {}; // 本身不具备Iterator接口 // 对于 Set 结构,也可以使用数组的解构赋值。 利用new Set数据去重 let [...arr] = new Set([1,2,3,4,4,4,4]) // arr = [1,2,3,4] // 交换变量 let [A,B] = [1,2] [B,A] = [A,B] // A=2,b=1
设置数组变量的默认值
// 要满足完全等于undefined,默认值才有效 let [a=2,b=1] = [undefined ,null]; // a=2;b=null // 惰性求值,只有匹配符合undefined的时候,才去调用函数求值 let [ a = foo() ] = [2]; => let a; if([2][0]===undefined){ foo() }else{ a = [2][0] } // 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。 let [x = 1,y=x] = []; // 不会报错 let [x = y,y=1] = []; // x赋值y时,y还没有被声明
# 2、对象的解构赋值
基本用法
let { x, y, z } = { x: 1, y: "2", z: 3 }; // x=1;y='2';z=3
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { boo, foo, coo } = { foo: 112, boo: "233" }; // boo='233' foo=112 coo=undefined
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
let { log, sin, cos } = Math; const { log } = console; log("hello"); // 'hello' // 取别名,内部是先召回再赋值 const {log:log} = console; 所以可以取别名代替 const { log: lg } = console; lg("hello"); // 'hello' // 嵌套的解构赋值一 let obj = { p: ["Hello", { y: "World" }] }; let { p: [x, { y }] } = obj; // y: 'World' x:'Hello' let { p, p: [x, { y }] } = obj; // y: 'World' x:'Hello' p: ["Hello", {y: "World"}] // 嵌套的解构赋值二 const node = { loc: { start: { line: 1, column: 5 } } }; const { loc, loc: { start, start: { line, column } } } = node; // line:1 , column:5 // 嵌套赋值 let aoo = []; let boo = {}; ({ foo: aoo[0], bor: boo["prop"] } = { foo: true, bar: 123 }); // aoo= [true] // boo={prop:123}
设置对象变量的默认值
默认值生效的条件是,对象的属性值严格等于
undefined
。let { x: y = 5 } = { x: 1 }; // y = 1 let { x: y = 5 } = {}; // y = 5 var { message: msg = "Something went wrong" } = {}; // msg = 'Something went wrong' // 注意:对象的解构为了{}不被js引擎理解为代码块,最好用() // 正确的写法 let x; ({ x } = { x: 1 }); // 无意义但合法 ({} = [true, false]); ({} = "abc"); ({} = []); //由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。 let arr = [1, 2, 3]; let { 0: first, [arr.length - 1]: last } = arr; first; // 1 last; // 3
# 3、字符串的解构赋值
字符串解构赋值。字符串被转换成了一个类似数组的对象。
const [a, b, c] = "Hello"; // a = 'H' b = 'e' c ='o' // 利用这个特点写一个文字乱序 const Text = "Hello"; const newT = [...Text].sort(() => Math.random() - 0.5).join(); // 类似数组的对象有length属性,应用解构赋值 const Text = "Hello"; const { length: len } = Text; len; // 5
# 4、数组和布尔的解构赋值
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于
undefined
和null
无法转为对象,所以对它们进行解构赋值,都会报错。let {proxy:1} = null || undefined // 报错 // 将等号右边的数字和布尔转化成了对象,将toString属性解构出来 let {toString: s} = 123; s === Number.prototype.toString // true let {toString: s} = true; s === Boolean.prototype.toString // true
# 5、函数的解构赋值
函数的参数也可以使用解构赋值。
function test([a, b]) { return a + b; } test([1, 2]); // 3 // 数组分批对应 7 无对应, 未加 [ [1, 2, 3], [4, 5, 6, 7] ].map(([a, b, c]) => a + b + c); // [6, 15]
函数参数使用默认值
function move([a = 9, b = 99]) { return [a, b]; } move([1, 2]); // [1,2] move([]); // [9,99] move([1]); // [1,99] move([undefined, 8]) // [9,8] [ // undefined就会触发函数参数的默认值。 (1, undefined, 3) ].map((x = "yes") => x); // [1,'yes',3]
# 6、解构赋值的用途
(1)从函数返回多个值
let [a, b] = ([1, 2][(a, b)] = [2, 1]);
// a = 2 ; b = 1
(2)接收从函数返回的多个值
函数只能返回一个值,想返回多个需要返回一个对象或数组,用解构赋值取值非常方便
function exam(){
return [1,2,3]
}
let [a,b,c] = exam() // a=1;b=2;c=3
function exam(){
return {foo:'hi',too:'hello'}
}
let {foo:fo , too:to} = exam() // fo:'hi' // to:'hello'
(3)函数参数的定义
利用数组解构的特点,会按顺序匹配
function test([x,y,z]){ ... }
test([1,2,3])
利用对象解构的特点:会自动找key相同的变量值
function test({x,y,z}){ ... }
test({x:2,z:3,y:1})
(4)提取 JSON 数据
解构赋值对提取复杂的json数据非常方便;
const JsonData = {
id: 43,
status: "OK",
data: [100, 200]
};
let { id, status, data: dataSource } = JsonData;
console.lgo(id, status, dataSource); // 43,'OK',[100,200]
(5)函数参数的默认值
function test(foo='nihao',too='hi'){
...
}
指定函数参数的默认值,当某个参数不传时可以使用默认值代替,不用像之前too||'default too'
(6)遍历 Map 结构
任何部署了 Iterator 接口的对象,都可以用 for...of 循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。
const map = new Map();
map.set('first','Hello')
map.set('second','World')
for([a,b] of map){
console.log(a + "is" + b ) // first is Hello // second is World
}
// 只获取key
for([a] of map) {...}
// 只获取value
for([,b] of map) {...}
(7)输入模块的指定方法
在导入模块时直接将里面的方法解构出来
import { connect } from "dva";
2020-02-24
5:42pm