欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ES6 - 基础学习(3): 变量的解构赋值

程序员文章站 2022-03-10 20:36:56
上接 ES6 - 基础学习(3): 变量的解构赋值 函数参数的解构赋值 1、基本用法 function add([x, y]) { return x + y; } console.log(add([1, 2])); // 3 // 如上面代码所示,函数add的形参表面是一个数组,但在实参参数传入时, ......

上接 es6 - 基础学习(3): 变量的解构赋值

函数参数的解构赋值

1、基本用法

function add([x, y]) {
    return x + y;
}

console.log(add([1, 2]));                                   // 3
// 如上面代码所示,函数add的形参表面是一个数组,但在实参参数传入时,实参数组就被解构并赋值给变量x、y了。当然这些对于函数内部的代码来说,跟参数一个个传入是一样的,反正都只认参数x、y

[[1, 2], [3, 4]].map(([a, b]) => a + b);
console.log([[1, 2], [3, 4]].map(([a, b]) => a + b));       // [3, 7]   1+2=3,3+4=7     map函数以二维数组内每个成员数组作为参数,进行参数解构,然后计算每个成员数组内参数值之和

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

// 下面代码中,函数defaultparameter的形参是一个对象(空对象)。通过对这个对象进行解构,得到变量x、y的值,如果解构失败,x、y就等于默认值。
function defaultparameter({x = 0, y = 0} = {}) {
    console.log([x, y]);
    return [x, y];
}
defaultparameter({x: 1, y: 2}); // [1, 2] defaultparameter({x: 3}); // [3, 0] defaultparameter({}); // [0, 0] defaultparameter(); // [0, 0] // 注意,下面这种写法会得到不一样的结果。区别在于此处是给参数指定默认值,而不是给变量x、y指定默认值。 // 这两种写法的执行区别是:上一种写法 实参传入函数后,实参对象内没有对应属性的值,则函数参数采用变量已有的默认值进行相关处理,代码依然能正常执行,不会报错。 // 而下一种写法 实参传入函数后,实参对象内没有对应属性的值,则就真没有了,函数参数因为解构赋值操作,无对应属性值的变量就只能等于undefined。这时如果再执行代码,尤其是计算类相关操作,执行就会报错,代码就会中断执行。 function defaultparameter({x, y} = {x: 0, y: 0}) { console.log([x, y]); return [x, y]; }
defaultparameter({x: 1, y: 2}); // [1, 2] defaultparameter({x: 3}); // [3, undefined] defaultparameter({}); // [undefined, undefined] defaultparameter(); // [0, 0] 没有传入参数,函数以默认对象进行解构赋值
// undefined会触发函数参数的默认值。
[1, undefined, 3].map((x = 'yes') => x);
console.log([1, undefined, 3].map((x = 'yes') => x));       // [1, "yes", 3]

圆括号问题

解构赋值虽然使用很方便,但是解析起来却不容易。对于编译器来讲,一个式子到底是模式,还是表达式,一开始并不知道,只有等到解析到(或解析不到)等号时才能知道。而由此带来的问题,如果模式中出现圆括号怎么处理。
es6的规则是,只要一个式子中有可能出现解构操作 或 可能让解构操作产生歧义的,就不得使用圆括号。
但是,这条规则实际操作起来却不那么容易辨别,处理起来也相当麻烦。因此,建议在实际开发中,除非很有必要,否则就不要在模式中放置圆括号。

// 以下三种解构赋值不得使用圆括号。
// 变量声明语句,模式不能使用圆括号
let [(a)] = [1];
let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};
let { o: ({ p: p }) } = { o: { p: 2 } };

// 函数参数也属于变量声明,因此不能带有圆括号
function f([(z)]) { return z; }
function f([z,(x)]) { return x; }

// 赋值语句的模式
({ p: a }) = { p: 42 };                                 // 将整个模式放在圆括号之中,导致报错
([a]) = [5];

[({ p: a }), { x: c }] = [{}, {}];                      // 将一部分模式放在圆括号之中,导致报错
// 可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号。
// 下面三行语句圆括号使用正常,代码执行也正确。因为它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。
// 第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是p,而不是d;第三行语句与第一行语句的性质相同。
[(b)] = [3];
({p: (d)} = {});
[(parseint.prop)] = [3];

解构赋值的用途

变量的解构赋值用途很多

1、变量值交换

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

2、函数返回多个值

// js中,一个函数一次只能返回一个值,如果想要返回多个值,则只能将 需要返回的值封装在数组或对象里一起返回,而且返回后取值还是一个麻烦问题。但有了解构赋值,取出这些值就方便很多了。
function returnsarray() {
    return [1, 2, 3];                                   // 返回一个数组
}
let [a, b, c] = returnsarray();
console.log(a);                                         // 1
console.log(c);                                         // 3

function returnsobject() {
    return {                                            // 返回一个对象
        name: 'es6',
        description: 'es6解构赋值 补充'
    };
}
let {name, description} = returnsobject();
console.log(name);                                      // es6
console.log(description);                               // es6解构赋值 补充

3、函数参数的定义

// 解构赋值可以很方便地将一组参数与变量名对应起来。
// 参数是一组有次序的值:数组
function testfunc([x, y, z]) {
    console.log(x, y, z);                               // 1 2 3
}
testfunc([1, 2, 3]);

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

4、函数参数的默认值

// 参数是一组有次序的值:数组
function testfunc([x = 0, y = 0, z = 0]) {
    console.log(x + y + z);
}
testfunc([1, 2]);                                       // 3        实参 少于 形参个数,形参取默认值
testfunc([123, 234, 345]);                              // 702      实参 等于 形参个数,形参按位置对应取值
testfunc([12, 23, 34, 45]);                             // 69       实参 多余 形参个数,形参按位置对应取值,多余剩下的不管。

// 参数是一组无次序的值:对象
function test_func({x = 0, y = 0, z = 0}) {
    console.log(x + y + z);
}
test_func({x: 1, y: 2});                                // 3        实参对象内属性名 与 形参变量名不能一一对应(属性名个数和变量个数不等),未能正确匹配的形参变量 取默认值
test_func({x: 1, y: 2, z: 3});                          // 6        实参对象内属性名 与 形参变量名一一对应,形参变量 按名一一对应 取值
test_func({x: 1, y: 2, aa: 4});                         // 3        实参对象内属性名 与 形参变量名不能一一对应(属性名个数和变量个数相等),未能正确匹配的形参变量 取默认值

5、提取 json 数据

// 解构赋值对快速提取 json 对象中的数据,尤其有用。
let jsondata = {
    name: 'es6',
    description: 'es6解构赋值 补充',
    time: [2015, 6]
};
let {name, description, time: number} = jsondata, [year, month] = number;
console.log(name);                                      // es6
console.log(description);                               // es6解构赋值 补充
console.log(year);                                      // 2015
console.log(month);                                     // 6

6、获取 set 数据结构内数据、 遍历 map 数据结构

// set数据结构是es6新增的一种数据结构,是一种类数组 数据结构,只是set结构实例内各个成员是唯一的,不允许重复。
// map则是es6新增的另一种数据结构,是一种类对象 数据结构,同样map实例内的属性也不允许重复,而且map结构内 属性字段不限数据类型。
// 任何部署了 iterator接口的对象,都可以用 for...of 循环遍历。map结构原生支持 iterator接口,配合变量的解构赋值,可以更方便的获取键名和键值。
let tempset = new set([1, 2, 'name', 'description']);
console.log(tempset);                                   // set(4) {1, 2, "name", "description"}
let [a, b, c, e] = tempset;
console.log(a);                                         // 1
console.log(b);                                         // 2
console.log(c);                                         // name
console.log(e);                                         // description

let tempmap = new map();
tempmap.set('name', 'es6').set('description', 'es6解构赋值 补充');
for (let [key, value] of tempmap) {
    console.log(key + " is " + value);
}

// 若只想获取键名,或只想获取键值,都可以。
for (let [key] of tempmap) {
    console.log(`键名: ${key}`);                        // 遍历键名
}

for (let [, value] of tempmap) {
    console.log(`键值: ${value}`);                      // 遍历键值
}

  ES6 - 基础学习(3): 变量的解构赋值

7、输入模块的指定方法

加载其他模块时,如果不想加载整个模块,则可以通过解构赋值的方式指定输入要加载的方法,从而既可以减少依赖加载,又可以使得输入语句清晰明了。

const {sourcemapconsumer, sourcenode} = require("source-map");