变量的解构赋值--ES6

1. 数组的解构赋值

基本用法

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

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

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

// set 结构也可以
let [x, y, z] = new Set(['a', 'b', 'c']);

// Iterator 接口的也可以
function* fibs(){
  yield 1;
  yield 2;
  yield 3;
  yield 4
}

let [first, second, third] = fibs();
third // 3

默认值
let [a=2] = [1];

若值为全等 undefined, 则才为默认值
let [a=2] = [undefined]; // a=2
let [a=2] = [null]; //a = null
let [a=2] = null; // 报错, 如果模式不是数组, 因为会两边不匹配
let [a=2] = undefined; // 报错

若默认值是一个表达式, 那么这个表达式是 惰性求值, 只有用到的时候才会求值
function f(){
  console.log('fffff'); // 这里不会执行
}
let [a=f()] = [1];
a; // 1

// 相当于执行了下面
if( [1][0] === undefined ){
  a = f();
}else{
  a = 1;
}

2. 对象的解构赋值

let {a=3} = {a: 1};
a; // 1

其实相当于:
let {a: a=3} = {a: 1};
// 有点类似于下面的写法
let _temp = {a: 1};
let a = _temp.a || 3;

 

解构赋值给空数组和空对象

let [a=3] = {} // ?会报错: Uncaught TypeError: undefined is not a function
let {a=3} = [] // 正确 a = 3;

下面的两种写法是一样的, 数组元素是按次序, 变量的取值由它对应的属性名决定。
let {a, b} = {a: 1, b: 2}
let {b, a} = {a: 1, b: 2}

如果变量名与属性名不一致, 写成下面这样, a 是匹配的模式, c 才是变量
let {a:c} = {a: 1, b: 2}
c; //1

说明对象的解构赋值是下面形式:
let {a, b} = {a: 1, b: 2};
// 等价于下面
let {a:a, b:b} = {a: 1, b: 2}

 

对象也可以进行嵌套
let {a: [{b}, c]} = {a: [{b: 2}, 3]}

a; // undefined
b; // 2
c; // 3

嵌套赋值例子:
let obj = {};
let arr = [];

( {a: obj.q, b: arr[0]} = {a: 1, b: 2} );
obj; // {q: 1}
b; // [2]


解构也可以指定默认值, 也是必须 === undefined
let { a=3 } = {a: 1};
a; //1

let { a=3 } = {a: null};
a; //null

let {a=4} = {a: undefined};
a; // 4

如果解构失败,变量的值等于undefined
let {a} = {b: 2};
a; // undefined


如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
// 报错
let {foo: {bar}} = {baz: 'baz'};
相当于:
let _temp = {baz: 'baz'};
{bar} = _temp.foo;
bar = _temp.foo.bar;

已经声明的变量用于解构赋值, 会将 {x}理解成一个代码块 而不是一个语句, 所以要有括号
let x;
{x} = {x: 1}; // Uncaught SyntaxError: Unexpected token =

let x;
({x} = {x: 1}); // 正确

{foo} = {foo: 1}; // 若不用let 也是正确的, foo 直接挂载到 window 下


3. 字符串的解构赋值
// 字符串转换成 类似数组
const [a,b] = 'hello';
a; // h
b; // e

// 字符串类似对象, 它有一个length 的属性
let {length : len} = 'hello';


4. 数值和布尔值的解构赋值
数值和布尔值都会转好成 包装对象

// 相当于s = 123.toStirng
let {toString: s} = 123;

// 相当于 s = true.toString
let {toString: s} = true;

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

let {a: 1} = null; // error
let {a: 1} = undefined; // error


5. 函数参数的解构赋值
function add([x, y]){
  return x + y;
}

add([1, 2]); // 3
相当于 [x, y] = [1, 2];

对于 map
// [5, 10]
[1, 2].map( (a) => a *5 );

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


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

// 只有当传递的参数为undefined 或不传参数的时候, 才会执行 {a, b} = {a: 1, b: 3}
function move({a, b} = {a: 1, b: 2}){
  return [a,b]
}
move({a: 3, b: 4}); // [3, 4];                     等价 {a, b} = {a: 3, b: 4}
move({a: 3});       // [3, undefined];             等价 {a, b} = {a: 3}
move({});           // [undefined, undefined];     等价 {a, b} = {}
move([]);           // [undefined, undefined];     等价 {a, b} = []
move(null);         // 报错;                        等价 {a, b} = null
move();             // [1, 2];                     等价 {a, b} = {a: 1, b: 2}
move(undefined);    // [1, 2];                     等价 {a, b} = {a: 1, b: 2}

// 同上面道理
function move({x = 0, y = 0} = {x: 100, y: 200}) {
  return [x, y];
}

move({x: 3, y: 4});   // [3, 4]
move({x: 3});         // [3, 0]
move({});             // [0, 0]
move();               // [100, 200]

 

undefined就会触发函数参数的默认值。
[1, undefined, 3].map( (a = 2) => a ); // [1, 2, 3]

 

6. 圆括号的问题
使用圆括号的情况

赋值语句并且非模式部分,可以使用圆括号。
({ p: (d) } = {p: 3}); // 正确, 这里d是非模式, p是模式, 最后 d = 3
let ({ p: (d) } = {}); // 错误, 因为是声音语句

[(b)] = [3]; // 正确, 说明这个b是非模式部分, 有点类似于 [0:(b)] = [3], 直接这么写会报错
({(a)} = {a: 3}); // 错误, 说明是这么执行 {(a): a} = {a: 3}; 括号加在了 a的模式部分


7.用途

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

2) 从函数返回多个值
function f(){
  return {
    a: 1,
    b: 2
  }
}

let {a, b} = f();

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

3) 函数参数的定义
function f([x, y, z]){
  console.log(arguments[0]); // [1,2,3]
  console.log(x, y, z);
}
f([1,2,3]);

function f({x, y, z}){
  console.log(arguments[0]); // arguments[0] 其实就是 {x: 1, y:2, z: 3}
  console.log(x, y, z); // x = 1, y = 2, z = 3;
}
f({x: 1, y: 2, z: 3});

4) 提取JSON数据
let o = {
  a: 1,
  b: 2
}

let {a, b} = o;

5) 函数参数的默认值
function f({x = 2, y = 3}){
  console.log(x, y);
}
f({});
f(); // error, 必须至少传入空对象, 否则会报错

6)遍历Map结构
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for(let item of map){
  console.log(item); // item 分别输出 ["first", "hello"], ["second", "world"]
}

所以可以写成:
for(let [key, value] of map){
  cnosole.log(key, value);
}

// 获取key 的值
for( let [key] of map){
  console.log(key);
}

// 获取value 的值
for( let [, value] of map){
  console.log(value);
}

7)输入模块的指定方法
const {a, b} = require('./test2')
import {a, b} from './test2';

 

转载于:https://www.cnblogs.com/zhengming2016/p/7068599.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值