美文网首页
04- 解构赋值

04- 解构赋值

作者: 夏海峰 | 来源:发表于2018-08-21 15:08 被阅读12次

1、ES6 解构赋值、数组解构

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

let [a,b,c] = [1,2,3];
console.log(b);

let [foo, [[bar], baz]] = [1, [[2], 3]];

let [ , , third] = [1, 2, 3];
console.log(third);


let [head, ...tail] = [1,2,3,4];
head;  // 1
console.log(tail); // [2,3,4]


let [x,y,...z] = ['geek'];
x;  // 'geek'
y;  // undefined    // 如果解构不成功,变量的值就等于undefined。
console.log(z);  // []

对Set结构进行解构:

let [m,n] = new Set(['1', '2']);
console.log(m);

事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值

解构赋值允许指定默认值:

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

let [s, t = 2] = [1];
t;   // 2

let [w, v='xia'] = ['geek', undefined];
v;   // 'xia'

let [j = 1] = [undefined];
j;   // 1

let [h = 1] = [null];
h;   // null
// 因为 null !== undefined

let [x = 1, y = x] = [];
// x = y = 1;
let [x = 1, y = x] = [100];
// x = y = 100;
let [x = 1, y = x] = [200, 300];
// x = 200,  y = 300
let [x = y, y = 1] = [1];  // 报错,y is undefined

2、解构不仅可以用于数组,还可以用于对象

对象的解构与数组的解构 有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let obj = {foo: 'aaa', bar: 'bbb'};
let { foo, geek } = obj;
console.log(foo);  // 'aaa'
console.log(geek); // undefined

let { bar: b } = obj;
console.log(b);   // 'bbb'

let { foo: f } = { foo: 'geek' };
// foo is undefined  // foo是匹配模式
// f = 'geek';       // f 才是变量

对象解构嵌套:

let obj2 = {
    p: ['hello', {y: 'world'}]
};
let {p: [x:x, {y:z}]} = obj2;
// x = 'hello'
// z = 'world'
// p 是匹配模式,它不是变量
// y 是匹配模式,它不是变量

对象解构 与 匹配模式:

const node = {
    loc: {
        start: {
            line: 1,
            column: 4
        }
    }
}
let { loc, loc: {start}, loc: {start: {line, column}}} = node;
// loc变量
// start变量
// line变量
// : 前面的是匹配模式


let obj3 = {};
let arr3 = [];
({foo: obj3.prop, bar: arr3[0]} = { foo: 123, bar: true});
// foo 是匹配模式, obj3.prop 是变量
// bar 是匹配模式, arr3[0] 是变量

对象解构 指定默认值:

var { x = 3 } = { x: undefined };
// x = 3
let { y = 3} = { y : null };
// y = null

实例,从Math对象中解构出三个函数:

let { log, sin, cos } = Math;

由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

let arr = [1, 2, 3];
let {0: first, 1: second, [arr.length-1]: last} = arr;
// first = 1
// second = 2
// last = 3

// 把数组看成特殊的对象
let arrObj = {
    0: 1,
    1: 2,
    3: 2
}

3、字符串的解构赋值

const [a,b,c,d,e] = 'hello';
// a = 'h'
// e = 'o'

let {length: len} = 'hello';
// length是匹配模式,字符串有这个属性
// len = 5

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

let { toString: s } = 123;
let { toString: t } = true;

5、函数参数的解构赋值

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

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

函数参数解构使用默认值:

function move({x=0, y=0} = {}) {
    return [x,y];
}
move({x:3, y:8});  // [3,8]
move({x:3});  // [3,0]
move();  // [0,0]

[1, undefined, null, true].map((x = 'yes') => x);
// [1, 'yes', null, true]

6、解构赋值 与 圆括号问题

let [(a)] = [1];   // 报错,模式不能使用圆括号

[(b)] = [3];  // 正确,赋值语句的非模式部分,可以使用圆括号

7、解构赋值的应用
应用1:交换两个变量的值

let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x,y);  // 2, 1

应用2:从函数中返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。

function returnArray() {
    // 返回一个数组
    return [1, 2, 3];
}
let [a, b, c] = returnArray();

function returnJson() {
    // 返回一个对象
    return {
        m: 1,
        n: 2
    }
}
let { m, n: aN } = returnJson();

应用3:函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来。

// 有序参数
function f1([x,y,z]) { };
f1([1, 2, 3]);

// 无序参数
function f2({x,y,z}) { };
f({ z: 3, x: 1, y: 2});

应用4:提取JSON中的数据

let data = {
    id: 42,
    status: 'ok',
    names: ['geek', 'xia']
}
let { id, status, names:myNames } = data;

应用5:函数参数的默认值

jQuery.ajax = function(url, {
    async = true,
    beforeSend = function() {},
    cache = true,
    complete = function() {},
    crossDomain = false,
    global = true,
    method = 'GET'
} = {}) {
    // do something
}
// 调用并覆盖部分默认参数
jQuery.ajax(url, {method: 'POST', async: false});

应用6:遍历Map结构

任何部署了 Iterator 接口的对象,都可以用for...of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。

const map = new Map();
map.set('a', 1);
map.set('b', 2);

// 从Map结构中取出所有键值
for(let [key, value] of map) {
    console.log(key + ' - ' + value);
}

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

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

应用7:使用模块中的指定方法

const { method1, method2 } = require('source-map');

完!!!

相关文章

网友评论

      本文标题:04- 解构赋值

      本文链接:https://www.haomeiwen.com/subject/viqjiftx.html