ES6-变量的解构赋值

更新日期: 2019-04-07阅读: 2.6k标签: 变量

1、解构赋值简介

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

举个例子,想获取数组中的前三个元素,通常会这么写:

var arr =[111,222,333];
var first = arr[0];
var second = arr[1];
var third = arr[2];

如果使用解构赋值的特性,将会使等效的代码变得更加简洁并且可读性更高:

let [first, second, third] = arr;

本质上,这种写法属于“模式匹配”、“映射关系”。

只要等号两边的模式相同,一一对应,左边的变量就会被赋予右边对应的值。

这种赋值语法极度简洁,同时还比传统的属性访问方法更为条理清晰。

当然,世间万物并不是完美的,例如下面的例子:

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

注意:左边数组中的 y 没有找到右边数组中对应值,解构不成功,变量 y 的值就等于undefined。

我们也可以给解构的对象设置一个默认值

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

左边数组中的 y 的有了默认值 “b”。

把解构赋值说的更通俗点,有点类似于“庖丁解牛” 。庖丁心里先设想把牛(Array、Object等)分解成很多块,然后按照规划好的想法,一刀刀对应起来,就把牛分解了。


2、数组的解构赋值

2.1 数组解构赋值特点

// ES6 之前
var a=1; 
var b=2; 
var c=3;

// ES6 之后
let [a,b,c] = [1,2,3];

这样可以用简单的方式将数组的值分别赋值到多个变量中。

数组的解构赋值特点:根据数据的下标来赋值的,有次序。

本质上,只要等号两边模式一致,左边变量即可获取右边对应位置的值。

2.2 可以对任意深度的嵌套数组进行解构

能够非常迅速的获取二维数组、三维数组,甚至多维数组中的值

let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz);  // 3

2.3 不需要匹配的位置可以置空

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

2.4 使用...扩展运算符,匹配余下的所以值,形成一个数组

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

这个'三点式'运算符我们用的比较多,比如用在数组合并上,

//ES5
var arr1 = [8]
var arr2 = [9,11,12,13]
arr1.push(arr2);
//[8,[9,11,12,13]]
Array.prototype.push.apply(arr1,arr2);
//[8,9,11,12,13]

// ES6
arr1.push(...arr2);
console.log(arr1)
//[8,9,11,12,13]

大家可以看到ES6明显写起来简洁很多。


3、对象的解构赋值

3.1 对象的解构赋值特点

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

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

let { a, b } = { a: "111", z: "222" };
a // "111"
b // undefined

上面的例子中,变量名与属性名不一致,可以改写成下面这样:

let { a, z:b } = { a: "111", z: "222" };
a // "111"
b // "222"

对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

3.2 可以对任意深度的嵌套对象进行解构

let itemObj = {
   arr: [
      "aaa",
      { secondLevel: "bbb" }
    ]
 };
 let { arr: [firstLevel, { secondLevel }] } = itemObj;
 console.log(firstLevel); // "aaa"
 console.log(secondLevel); // "bbb"

3.3 可以自定义属性名称

var {name, id: ID} = { name: 'jack', id: 1    };

ID // 1
id // Uncaught ReferenceError: id is not defined

但要注意的是被赋值的只是我们自定义的属性名称,匹配的模式(项)并未被赋值


4、字符串解构

字符串也可以解构赋值,字符串被转换成了一个类似数组的对象。模式能够匹配起来,如:

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

let { length:len } = 'hello';
console.log(len);  //5 (长度为5)


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

解构赋值的规则是:只要等号右边的值不是对象或数组,就先将其转为对象。如果转换之后的对象或原对象拥有Iterator接口,则可以进行解构赋值,否则会报错。

// 数值和布尔值的包装对象都有toString属性
let {toString: str} = 111;
str === Number.prototype.toString // true

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

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

以上的数组和布尔值会转换成对象,toString模式匹配上了对象的toString属性,所以解构成功。

而null或undefined却不能转换成此类对象,所以报错。

ES6中引入了Iterator迭代器,集合Set或Generator生成器函数等都部署了这个Iterator接口,所以也可以用来进行解构赋值。Set的解构赋值例子如下:

var [a, b, c] = new Set([1, 2, 3]);
a // 1
b // 2
c // 3


6、圆括号的用法

如果在解构之前就已经定义了对象

let obj;
{obj}={obj:'James'};
console.log('James');  //报错

原因:

大括号{位于行首,匹配了}之后 JS引擎 就会认为 { obj } 是一个代码块,所以等号就出问题了,解决方式是在行首放个括号(,即外包裹一层括号()

let obj;
({obj}={obj:'James'});
console.log('James');  //James

括号的出现,让整个解构赋值的结构被看做一个代码块,而内部的 { obj } 模式则可以正常匹配到。


7、实际用途

7.1 交换变量的值

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


7.2 函数参数定义

// 参数是一组有次序的值
function foo([width,height,left,right]) { 
    //... 
}
foo([100, 200, 300, 300])

// 参数是一组无次序的值
function foo({width,height,left,right}){
     // ...
}
foo([left:300, width:100, right:300, height:200,])

为了实现设计良好的 api,通常的做法是为函数为函数设计一个对象作为参数,然后将不同的实际参数作为对象属性,以避免让 API 使用者记住多个参数的使用顺序。

我们可以使用解构特性来避免这种问题,当我们想要引用它的其中一个属性时,大可不必反复使用这种单一参数对象。

7.3 配置对象参数

jquery.ajax = function (url, {
      async = true,
      beforeSend = noop,
      cache = true,
      complete = noop,
      crossdomain = false,
      global = true,
      // ... 更多配置 
 }) {
      // ... 
 };

如此一来,我们可以避免对配置对象的每个属性都重复var foo = config.foo || theDefaultFoo;这样的操作。

7.4从函数返回多个值

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

// 返回一个对象
function foo2() {
  return {
    a: 1,
    b: 2
  };
}
let { a, b } = foo2();

7.5 引入模块的指定方法

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

如果项目中只用到了element-ui中的Loading模块,可以这么写:

import { Loading} from 'element-ui'


8、总结

8.1 解构赋值的定义

解构赋值,即对某种结构进行解析,然后将解析出来的值赋值给相关的变量,常见的有数组、对象、字符串的解构赋值等。

在语法上,就是赋值的作用,解构为(左边一种解构。右边一种解构,左右一一对应进入赋值)。

8.2 解构赋值的分类

1.左右为数组即为数组解构赋值。

2.左右为对象即为对象解构赋值。

3.左边是数组,右边是字符串,为字符串解构赋值。

4.布尔值解构赋值为字符串的一种。

5.函数参数解构赋值即为数组解构赋值在函数参数的一种应用。

6.数值解构赋值为字符串解构赋值的一种。

8.3 解构赋值的优势

变量的解构赋值就是一种写法,掌握了这种写法可以让我们在书写 javascript 代码时可以更加的简单,迅捷。在很多独立细小的方面,解构赋值都非常有用。这些新的特性和微小的改进结合起来,它终将会影响你工作中的每一个项目。

链接: https://fly63.com/article/detial/2744

css自定义变量_初次接触CSS变量

本文的目的主要是展示CSS变量是如何工作的。随着Web应用程序变得越来越大,CSS变得越来越大,越来越多,而且很多时候都很乱,在良好的上下文中使用CSS变量,为您提供重用和轻松更改重复出现的CSS属性的机制。

CSS变量(自定义属性)实践指南

Sass和Less这样的预处理器,让我们的CSS代码保持良好的结构和可维护性。像变量、混合(mixins)、循环控制等特性,增强了动态编写CSS的能力,从而减少重复代码,也加快了我们开发速度。

css变量_原生css 中变量的使用

原生css 中变量的使用,这个重要的 CSS 新功能,所有主要浏览器已经都支持了。本文全面介绍如何使用它,你会发现原生 CSS 从此变得异常强大。声明变量的时候,变量名前面要加两根连词线(--),var()函数用于读取变量。

理解var let const区别

JavaScript中var、let、const区别?js中let和const都是es5版本新的命名规范,在此之前定定义一个变量只能用var。我们可以把let和const看做是为了弥补var的一些不足而新设计出来的

一个例子,变量提升和函数提升就是这么简单!

引擎在读取js代码的过程中,分为两步。第一个步骤是整个js代码的解析读取,第二个步骤是执行。在JS代码执行之前,浏览器的解析器在遇到 var 变量名 和function 整个函数 提升到当前作用域的最前面。

CSS变量使用解析

很早直接就了解到CSS变量相关的内容,奈何之前使用价值不高(很多主流浏览器不兼容),最近发现主流浏览器都已经支持了这一变化,CSS变量就像JS的变量,每个类名或者花括号就像一个function,里面的变量只有上下文以内可以获取,这就让CSS有了更多可能性。

let与var的区别,为什么要用let?

var是全局声明,let是块级作用的,只适用于当前代码块;var变量会发生变量提升,let则不会进行变量提升;var 会造成重复赋值,循环里的赋值可能会造成变量泄露至全局

JS中变量的存储

JS中的变量是保存在栈内存中的:1.基本数据类型的值直接在栈内存中存储;2.值与值之间是独立存在的,修改一个变量不会影响其他变量;对象是保存到堆内存中的,每创建一个新的对象

js 交换变量值的方法总汇

这篇文章总结七种办法来交换a和b的变量值 。最最最简单的办法就是使用一个临时变量了 ,最后我的方案是利用了ES6的解构赋值语法 ,它允许我们提取数组和对象的值,对变量进行赋值

JavaScript 的共享传递和按值传递

我们可以说原始数据类型和引用数据类型的副本作为参数传递给函数。不同之处在于,在原始数据类型,它们只被它们的实际值引用。JS不允许我们获取他们的内存地址,不像在C与C++程序设计学习与实验系统

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!