ES6学习笔记二(变量结构赋值)

165 阅读5分钟
参考ES6标准入门书籍

数组的结构赋值

     首页我们来说一说什么是解构赋值,ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称为解构(Destructuting)

     多的不说我们直接来看几个解构的例子,想象你很快就能理解。

//以前的赋值写法
例1
var a = 1;
var b = 2;
var c = 3;
//ES6使用解构赋值
例2
var [a, b, c] = [1, 2, 3];
//复杂嵌套数组解构
例3let [a, [[b], c]] = [1, [[2], 3]];
a// 1
b// 2
c// 3
例4
let [ ,b, c] = ["1", "2"];
c// undefined 
b// "2"
a// a is not defined
例5
let [a, b] = [1, 2, 3];a// 1b// 2
例6let [a, ...b] = [1, 2, 3, 4];a//1b//[2, 3, 4]例7
//报错
let [a]=1;
例8
function* fibs() {    var a = 0;    var b = 1;    while (true) {      yield a;      [a, b] = [b, a + b];    }}var [first, second, third, fourth, fifth, sixth] = fibs();sixth // 5

我们可以清楚的发现只要等号两边的模式相同,左边的变量就会被赋予对应的值。

  1. 如果解构不成功变量的值就会变成undefined。(例4)
  2. 如果解构不完成,左边会匹配能够解构的那一部分,并不会出现错误。(例5)
  3. 如果解构的不是数组那么就会报错(例7)
  4. 解构可以配合...运算符一起使用(例6)
  5. 特殊情况,只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值。(例8)

设置默认值

解构赋值是可以设置默认值的我们来看一段代码

例1
let [a=1,b]=[];
a//1
b//undefined
例2
let [a=1]=[undefined];
a//1
例3
let [a=1,b]=[2,3]
a//2
b//3
例4
let [a=1,b=a]=[2]a//2b//2
例5let [a=b,b=1]=[]ReferenceError: b is not defined

  1. 我们可以发现等号左边的变量是可以设置默认值的,而且当右边匹配的值是undefined,左边的值还是默认值,如果不是undefined,则覆盖默认值。(例1例2例3)
  2. 默认值可以用用解构赋值的其他变量,但是这个变量必须已经声明。(例4例5)

其他类型的解构赋值

对象的解构赋值和数组有一个重要的不同,数组是按次序排列的,变量取值是由它的位置决定的;但是对象没有次序,对象是按照属性名取值的。我们看看例子。

例1
let {b,a}={a:1,b:2}
a//1
b//2
例2
let{b:first,a:last}={a:1,b:2}first//2
last//1
a//ReferenceError: a is not defined
b//ReferenceError: b is not defined

var obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

var { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ReferenceError: p is not defined
  1. 第一段代码我们可以看出对象的解构赋值和数组的区别,而且我们看到等号左边的变量名和属性名不一致时,必须按例2那样书写,其实例1的写法只是一种简写他和例2是一样的。

    let {b:b,a:a}={a:1,b:2}
    a//1
    b//2

  2. 第二段代码是复杂的对象的解构赋值,一眼看去你可能会觉得p也是变量,其实p这里只是一种模式,不会被赋值,如果我们要取p只能另外加一个变量。

    var { p,p: [x, { y }] } = obj;

字符串,数值和布尔值的解构赋值其实都差不多我们来看几个例子。

//字符串被转化成了一个类似数组的对象
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
//这个数组对象有一个length属性
let {length : len} = 'hello';len // 5

//解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
//数值
let {toString: s} = 123;s === Number.prototype.toString // true//布尔值let {toString: s} = true;s === Boolean.prototype.toString // true

函数参数的解构赋值

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

add([1, 2]); // 3
上面代码中,函数的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到的参数就是x和y。

应用

  1. 交换变量的值
  2. 函数返回多个值
  3. 函数参数自定义
  4. 提取Json数据
  5. 函数参数的默认值
  6. 遍历Map解构
  7. 输入模块的指定方法
一、首页我们来看第一个其实很简单

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

简简单单的代码实现了交换a和b的值

二、函数返回数据的时候,有时候会出现需要返回多个值的情况,这时候使用解构赋值就十分的合适了。

function f() {
  return [1, 2];
}
var [a, b] = f();
a//1
b//2

三、函数参数定义的时候使用解构赋值,可以让我们传如参数的时候变得十分方便

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

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

四、作为一个前端开发者我相信我们和json直接一定都有着很密切的关系,玩转json是我们必经之路。那么我们来看看解构赋值在提取json数据的时候带给我们的方便。

var jsonData = {
  id: 1,
  read: true,
};

let { id, read } = jsonData;
console.log(id, read);// 1, true

五、函数参数的默认值

指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句。

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};

六、遍历Map解构

在使用for...of循环遍历的时候,配合变量的解构赋值获取键名和键值变的十分方便

var map = new Map();
map.set('f', 'hello');
map.set('s', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
//f is hello
//s is world

七、输入模块的指定方法

加载模块时,往往需要指定输入那些方法。解构赋值使得输入语句非常清晰。

const { SourceMapConsumer, SourceNode } = require("source-map");