es6语法--解构赋值

文章目录


前言

本文用来记录解构赋值的语法以及它的用途。

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

一、基本用法

1.数组的结构赋值

注:数组的元素是按次序排列的,变量的取值由它的位置决定。 

//以前为变量赋值

let a = 1;
let b = 2;
let c = 3;

//es6写成如下:
let [a,b,c] = [1,2,3];

如上所示,可以从数组中提取值,按照对应位置,对变量赋值。  

解构赋值需要的是等号两边的结构相等。即可将等号右边的结果依据相同的结构赋予左边的变量。*如果等号左边的结构属于等号右边的结构的一部分的话, 还是可以实现解构赋值。

如果解构失败,那么变量就会被赋予 undefined。 

let arr = ['hello','world']
let [a,b] = arr
console.log(a); // hello
console.log(b); // world

let [one, [[two], three]] = [1, [[2], 3]];
one// 1
two// 2
three// 3

let [ , , three] = ["第一", "第二", "第三"];
three// "第三"

let [a, , c] = [1, 2, 3];
a // 1
c // 3

let [num, ...arr] = [1, 2, 3, 4];
num // 1
arr // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

let [foo] = [];  
foo //undefined

在数组结构赋值过程中,只要把每个解构的部分一一对应起来,就可以层层解构赋值。比如:

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4


let [a, b, d] = [1, [2, 3], 4];
a // 1
b // [2, 3]
d // 4

 [b] 这个语句,它对应的是实际数组中的 [2,3] ,因此这个语法解析的便是[2,3]中的元素,因此获得的应该是2这个数值。

如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。 

let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
//上面语句都会报错

对于 Set 结构,也可以使用数组的解构赋值。 

let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"

数组的解构赋值指定默认值 :

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2

 ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

 2.对象的解构赋值

注:对象的属性没有次序要求,变量必须与属性同名,才能取到正确的值。 

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined

如果变量名与属性名不一致,可以起别名(属性名:变量名),如下所示: 

let { oldName: newName} = { oldName: 'aaa', b: 'bbb' };
newName// "aaa"

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

与数组一样,解构也可以用于嵌套结构的对象。

const info= {
  data: {
    stu: {
      name: '小米',
      age: 20
    }
  }
};

let { data, data: { stu}, data: { stu: { name}} } = info ;
name // 小米
data //  {stu:{name: '小米',age: 20}}
stu //  {name: '小米',age: 20}


let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
obj // {prop:123}
arr // [true]

上面第一段代码有三次解构赋值,分别对data、stu、name三个属性的解构赋值。最后一次对name属性的解构赋值之中,只有name是变量,data和stu都是模式,不是变量。

第二段代码中 把一个已经声明的变量用于解构赋值,要将整个解构赋值语句,放在一个圆括号里面。如果不加圆括号js会将{foo:obj.prop,bar:arr[0]} 从而发生语法错误。

注:要将一个已经声明的变量用于解构赋值,要将整个解构赋值语句,放在一个圆括号里面

可以使用圆括号的情况 :赋值语句的非模式部分,可以使用圆括号

[(a)] = [1]; 
({p: (d)} = {});
[(parseInt.prop)] = [3]; 

对象的解构赋值指定默认值 : 

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x: y = 3} = {};
y // 3

var {x: y = 3} = {x: 5};
y // 5

var {x = 3} = {x: undefined};
x // 3

var {x = 3} = {x: null};
x // null

默认值生效的条件是,对象的属性值严格等于undefined。 

3.字符串的解构赋值 

let {length:len} = 'hello';
len // 5   解构赋值的是字符串的length属性

let [a,b,c] = 'hello';
a  // h
b  // e
c  // l   字符串可以当成一个数组解构赋值,解构的是对应的每个字符

4.数值和布尔值的解构赋值 

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。 由于undefinednull无法转为对象,所以对它们进行解构赋值,都会报错。

注:只要等号右边的值不是对象或数组,就先将其转为对象。 

5.函数参数的解构赋值 

 函数的参数也可以使用解构赋值。

function add([x,y]){
    return x + y;
}
add([1,2]); // 3

[[1,2],[3,4]].map(([a,b]) => a + b );
// [3,7]


const user = {
    userName: "admin",
    passWord: "123456",
};
function show({userName, passWord}) {
    let message = `账户:${userName}:${passWord}`;
    console.info(message);
}
show(user);

函数参数的解构也可以使用默认值 :

function reArr({x=0,y=0}={}){
   return [x,y];
}
reArr({x:3,y:8});  // [3,8]
reArr({x:3});  // [3,0]
reArr({});  // [0,0]
reArr();  // [0,0]
//函数 reArr参数是一个对象,通过对这个对象进行解构,得到 x 和 y 的值。如果解构失败,x,y等于默认值。


function reArr({x,y} = {x:0,y:0}){
   return [x,y];
}
reArr({x:3,y:8});  // [3,8]
reArr({x:3});  // [3,underfined]
reArr({});   // [underfined,underfined]
reArr(); // [0,0]
// 函数reArr的参数指定默认值,而不是为变量x和y指定默认值

undefined就会触发函数参数的默认值。 

[1,2,undefined].map((x = 'default') => x);
// [1,2,'default']

二、用途

1.交换变量的值

let x = 1;
let y = 2;
[x,y] = [y,x];
// 交换变量 x 和 y 的值

2. 函数返回多个值

function example(){
   return [1,2,3];
}
let [a,b,c] = example();

function example(){
    return{
       a:1,
       b:2
    }
}
let {a:aValue,b:bValue} = example();

3. 函数参数的定义

function fun([x,y,z]){...} //参数是一组有次序的值
fun([1,2,3]);

function fun({x,y,z}){...} //参数是一组无次序的值
fun({z:3,x:1,y:2});

4.提取JSON数据 

let data = {
   name:'小明',
   age:20,
   sex:'男',
   info:[123, 456]
}
let {name, age, sex, info:number} = data;
console.log(name,age,sex,number);
// 小明 20 男  [123, 456]

5.函数参数的默认值

jQuery.ajax = function (url,{  //{}为函数中参数设置默认值
   async = true,
   beforeSend = function(){},
   cache = true,
   complete = function(){},
   crossDomain = false,
   global = true
   // ...
} = {}){ //....
}

6.遍历Map结构 

配合变量的解构赋值,获取键名和键值。 

const map = new Map();
map.set('name','小小');
map.set('value','1220');
for(let [key,value] of map){
   console.log(key +':'+value);
}
// name:小小     value:1220

// 获取键名
for (let [key] of map) { // ...}

// 获取键值
for (let [,value] of map) { // ... }

7.输入模块的指定方法 

const { SourceMapConsumer, SourceNode } = require("source-map");
//加载模块时,可以通过解构赋值指定输入哪些方法

猜你喜欢

转载自blog.csdn.net/weixin_42464106/article/details/125552430