资讯专栏INFORMATION COLUMN

ES6解构赋值原理详解

wing324 / 2784人阅读

摘要:中还存在字符串数组布尔值等各种解构赋值,基本概念和原理都和对象的解构赋值类似,这里就不在全部列举了。

ES6解构赋值

ES6变量的解构赋值本质上是“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予匹配的右边的值,如果匹配不成功变量的值就等于undefined

数组的解构赋值

ES6中只要某种数据有Iterator接口(也就是可以循环迭代),都可以进行数组的解构赋值。
Example1:数组的解构

var [a,b,c] = [1,2,3];
var [d,[e],...f] = [4,[5],6,7,8];
console.log(a); //结果为1,b,c结果是2,3
console.log(e,f) //e结果为5,f的结果是一个数组:[6,7,8]

Example2:Set解构赋值

let [x,y] = new Set([1,2]);
console.log(x,y);   //结果为1和2

Example3:Generator函数解构赋值

function* fun(){
    let a = 0;
    let b = 1;
    while(true){
        yield a;
        [a,b] = [b,a+b];
    }
}
let [first,second,third,fourth,fifth,sixth] = fun();
console.log(sixth); //结果为5

Example4:默认值

var [a=3,b=5] = [undefined,4];
console.log(a,b); //结果为3和4

代码解读:上面的代码等同于如下:
Example4:

var a;
var b;
var c = [undefined,4];  //这步骤是另加上去作为数组引用的
if(c[0] !== undefined){
    a = c[0];
}else{
    a = 3;
}
if(c[1] !== undefined){
    b = c[1];
}else{
    b = 5;
}
console.log(a,b);   //结果为3,4
对象的解构赋值

数组的解构是按次序排列的,变量取值由位置决定的,而对象的属性是没有顺序的,变量必须与属性同名才能取到正确的值。

Example

var {b,a} = {a:3,b:4}
console.log(a,b);   //结果为3,4

代码解读:上面的代码等同下面的代码
Example

var _ab = {a:3,b:4};
var b = _ab.b;
var a = _ab.a;
console.log(a,b);   //结果为3,4

注意:对象的解构相当于先定义了后一个对象变量为_ab,再对前一个对象解构出来的变量按照对象先后顺序分别进行申明并使用对象_ab去按照该变量名赋值相应的值。如果前一个对象中的变量和后一个对象中的属性不一致,直接定义是肯定赋值失败的,解决方法如下:
Example

var {b:c,a:d} = {a:3,b:4};
console.log(b,c,a,d)    // 分别是undefined,4,undefined,3

代码解读:上面代码等同下面的代码

Example

var _ab = {a:3,b:4};
var c = _ab.b;
var d = _ab.a;
console.log(b,c,a,d)    // 分别是undefined,4,undefined,3

注意:例子可以看出对象的解构的内部机制是先找到同名属性,然后再赋予相应的变量,真正被赋予的是前一个对象后一个变量,即c,d;而不是前一个对象前一个模式,即b,a;

发现:如果想要上一个例子的模式不为undefined,那么代码可以写成如下:
var e = {b:c,a:d} = {a:3,b:4};
console.log(e.b,b,c,e.a,a,d)    // 分别是4,undefined,4,3,undefined,3

注意:以上代码在使用babel转换的时候可能会出错,只在浏览器中有用,所以最好不要代码中使用,只理解就好

对象解构赋值与数组解构赋值在申明的时候的一点区别:

Example1:数组

let a;
[a] = [3]
console.log(a); //结果为3

Example2:对象

let a;
{a} = {a:3}
console.log(a); // 报错:SyntaxError

代码解读:JavaScript引擎会将[a]理解成一个数组,而将{a}理解成什么呢?对于{a}这个代码在JS中可能会存在两种解释,一种是它是一个表达式,表示含有a属性的一个对象;第二种它是一个语句(代码块),为了消除这种歧义,js开发人员规定只要行首是大括号的,一律解析成代码块。解决上诉问题的代码如下:
Example3:对象

let a;
({a} = {a:3})   //JS中括号中的都是表达式
console.log(a); // 结果3
解构赋值中的圆括号问题

Example

let [(a)] = [1];
let {(b):c} = {b:2};
let {d:(e)} = {d:2};    //都报错:SyntaxError

注意:以上出现错误的原因都是:1、它们都是申明语句;2、圆括号中的都属于模式中的一部分。要同时不满足以上两个条件是比较困难的,所以,ES6规定,只要可能导致解构歧义就不得使用圆括号。所以,建议在写的过程中除了上面的那个对象圆括号的例子可以使用外,其他的情况都不能使用。

ES6中还存在字符串、数组、布尔值等各种解构赋值,基本概念和原理都和对象的解构赋值类似,这里就不在全部列举了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83986.html

相关文章

  • ES6语法详解(一)

    摘要:冻结对象可以使用方法。对象的解构赋值必须要属性名相同,顺序毫无影响。数组解构赋值默认值,当等号右边的值时,默认值生效。 let变量 let声明的变量在let命令所在的代码块中有效。不存在变量提升,只能先声明后使用。 暂存死区 如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量。 var a = 1; { ...

    wendux 评论0 收藏0
  • ES6学习手稿之基本类型扩展

    摘要:它是一个通用标准,奠定了的基本语法。年月发布了的第一个版本,正式名称就是标准简称。结语的基本扩展还有一些没有在这里详细介绍。 前言 ES6标准以及颁布两年了,但是,好像还没有完全走进我们的日常开发。这篇文章从ES6的基本类型扩展入手,逐步展开对ES6的介绍。 ECMAScript和JavaScript JavaScript是由Netscape创造的,该公司1996年11月将JavaSc...

    tommego 评论0 收藏0
  • ES6学习(二)之解构赋值及其原理

    摘要:基本原理解构是提供的语法糖,其实内在是针对可迭代对象的接口,通过遍历器按顺序获取对应的值进行赋值。属性值返回一个对象的无参函数,被返回对象符合迭代器协议。迭代器协议定义了标准的方式来产生一个有限或无限序列值。 更多系列文章请看 1、基本语法 1.1、数组 // 基础类型解构 let [a, b, c] = [1, 2, 3] console.log(a, b, c) // 1, 2, ...

    chunquedong 评论0 收藏0
  • ES6解构赋值运算符

    摘要:本次我领到的任务是在中有一个解构赋值运算符,可以大大方便数据字段的获取。解构赋值运算符配合会比较有用。 本次我领到的任务是: 在ES6中有一个解构赋值运算符,可以大大方便数据字段的获取。 比如 const [a, b] = [1, 2, 3]; const {name, age} = {name: helijia, age: 3}; 上面的语句是我们常用的,可是你能解释为什么下面的...

    qpal 评论0 收藏0
  • ES6 变量声明与赋值:值传递、浅拷贝与深拷贝详解

    摘要:变量声明与赋值值传递浅拷贝与深拷贝详解归纳于笔者的现代开发语法基础与实践技巧系列文章。变量声明在中,基本的变量声明可以用方式允许省略,直接对未声明的变量赋值。按值传递中函数的形参是被调用时所传实参的副本。 ES6 变量声明与赋值:值传递、浅拷贝与深拷贝详解归纳于笔者的现代 JavaScript 开发:语法基础与实践技巧系列文章。本文首先介绍 ES6 中常用的三种变量声明方式,然后讨论了...

    snowLu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<