变量的解构赋值

解构赋值是什么

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值

var/let [变量名称1,变量名称2,...] = 数组或对象

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值

解构赋值失败

如果解构不成功,变量的值就等于undefined

解构赋值失败 - 定义变量的数量大于值的数量

let [m,n] = [1];
console.log(m, n);//1 undefined
不完全解构赋值

等号左边的模式,只匹配一部分的等号右边的数组

不完全解构赋值 – 定义变量的数量小于值的数量

解构依然可以成功

let [a,b] = [1,2,3];
console.log(a, b);//1 2
默认值

解构赋值允许指定默认值

解构赋值失败时,变量的默认值为undefined
默认值–指的就是在解构赋值失败时,重写undefined默认值

ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效

let [a=true] = [100];
console.log(a);//100let [x, y = 100]= [10];
console.log(x,y);// 10 100// ES6底层将为变量赋值的值与undefined进行比较(全等于)
let [m,n = 100]=[10,undefined];
console.log(m,n);

ES6底层将为变量赋值的值只是与undefined进行比较(null等没有意义的)

let [v,w=100] = [10,null]
console.log(v, w);//10 null

对象的解构赋值

解构不仅仅可以用于数组,也可以用于对象

let {x,y}={x:10,y:20
}
console.log(x, y);//10 20
对象的解构赋值

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

  • 数组[] = 对象{}
let [m,n]= {m:20,n:10
}
console.log(m, n);// {(intermediate value)(intermediate value)} is not iterable
  • 对象{} = 对象{函数}
let {m,n}={m:100,n:function () {return 10;}
}
console.log(m, n());// 100 10
  • 数组[] = 数组[函数]
let [m, n] =[100,function(){return 10;}];
console.log(m,n());// 100 10
  • 对象{} = 对象{对象,函数}
let {m,n}={m: {name:'张无忌'},n:function () {return 10;}
}
console.log(m.name,n());// 张无忌 10
  • 数组[] = 数组[对象,函数]
let [m, n] =[{name:'张无忌'},function(){return 10;}];
console.log(n()); // 10
  • 数组[] = 数组[数组]
let [a,b] = [[1,2],3]
console.log(a, b);//[ 1, 2 ] 3
let [[a,b],c] = [[1,2],3]//等价于 let [a,b,c] = [1,2,3]
console.log(a, b, c);// 1 2 3
解构赋值失败
let {m,n}={m:100
}
console.log(m, n);//100 undefined

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错

// 报错
let {x: {y}} = {y: '123'};
默认值

对象的解构赋值也可以指定默认值。默认值生效的条件是对象的属性值全等于undefined。

let {x,y=1}={x:100
}
console.log(x, y);// 100
注意点(参考阮一峰的ECMAScript 6 入门)
// 错误的写法
let x;
{x} = {x: 1};
console.log(x)// 正确的写法
let x;
({x} = {x: 1});
console.log(x)

因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

  • 解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式
({} = [true, false]);
({} = 'abc');
({} = []);
  • 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
console.log(first, last);// 1 3

数组arr0键对应的值是1[arr.length - 1]就是2键,对应的值是3

字符串的解构赋值

字符串被转换成了一个类似数组的对象

let  [a,b,c]="xyz"
console.log(a, b, c);// x y zlet  [a,b,c]="xxyyzz"
console.log(a, b, c);// x x ylet  [a,b,c]="大前端了"
console.log(a, b, c);// 大 前 端

数值与布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象.

规则:

​ 解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefinednull无法转为对象,所以对它们进行解构赋值,都会报错。

let num = new Number(100);
console.log(num.toString());// 100//数字值或布尔值的解构赋值 - 先将数字值或布尔值转换成对象类型
let{toString:m}=100;//100本身就是number类型对象
console.log(m)// [Function: toString]let  {toString:x}=true;
console.log(x === Boolean.prototype.toString());//true

函数参数的解构赋值

函数参数的解构赋值
//函数定义 – 形参,相当于在函教作用域中定义了一个局部变量(没有赋值)
function fn(a,b) {console.log(a, b);//10 20
}
//函数调用 – 实参,相当于在函数作用域中为定义的变量进行赋值
fn(10,20)

形参传入什么格式在实参用相同的格式进行匹配

默认值
function move({x = 0, y = 0} = {}) {return [x, y];
}console.log(move({x: 3, y: 8})); // [3, 8]
console.log(move({x: 3})); // [3, 0]
console.log(move({})); // [0, 0]
console.log(move()); // [0, 0]

小括号的问题

小括号的问题

解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。

由此带来的问题是,如果模式中出现圆括号怎么处理。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];
可以使用它小括号的情况

赋值语句的非模式部分,可以使用小括号

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确

解构赋值的用途

  • 交换变量的值

解构赋值可用于两个变量之间交换值。

let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y);// 2 1
  • 从函数返回多个值

    函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。如果使用解构赋值的话,很容易实现函数返回多个值

    • 返回一个数组
    function fn() {return [1, 2, 3];
    }
    let [a, b, c] = fn();
    console.log(a, b, c);// 1 2 3
    
    • 返回一个对象
    function fn1() {return {a1: 1,b2: 2};
    }
    let { a1, b2 } = fn1();
    console.log(a1, b2);// 1 2
    
  • 函数参数的定义

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

    • 参数是一组有次序的值
    function f([a, b, c]) {console.log(a, b, c); // 1 2 3
    }
    f([1, 2, 3]);
    
    • 参数是一组无次序的值
    function f({q, w, e}) {console.log(q, w, e); // 3 2 1
    }
    f({e:1, w:2, q:3});
    
  • 函数参数的默认值

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

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

  • 提取JSON数据

解构赋值对于提取JSON对象中的数据内容尤其有用。

let jsonData = {name: "张无忌",age: 11,job: "教主"
};let { name, age, job } = jsonData;console.log(name, age, job);
// 张无忌 11 教主

[ES6] 细化ES6之 -- 变量的解构赋值相关推荐

  1. ES6阮一峰-----变量的解构赋值学习

    1.数组的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前,为变量赋值,只能直接指定值. let a = 1; let b = ...

  2. ES6新特性_变量的解构赋值---JavaScript_ECMAScript_ES6-ES11新特性工作笔记006

    然后我们再看,变量的解构赋值. 可以看到按照一定的模式,从数组和对象中提取数据,以及对对应的变量进行赋值 被称为解构赋值. 可以看到上面 let[xiao,liu,zhao,song]=F4 相当于我 ...

  3. ES6基础:变量的解构赋值

    ES6基础系列之变量的解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构.这种方式的出现大大提高了代码的扩展性 前言 一.数组的解构赋值 二.对象的解构赋值 三.函 ...

  4. 【ES6】变量的解构赋值

    [ES6]变量的解构赋值 一.什么叫解构赋值? 二.解构赋值有哪些分类?写法? 1)对数组的解构赋值 2)对对象的解构赋值 3)对字符串的解构赋值 4)对数值和布尔值的解构赋值 5)对函数参数的解构赋 ...

  5. ES6的新特性(3)——变量的解构赋值

    变量的解构赋值 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). let a = 1; let b = 2; le ...

  6. Vue2.x—理解vuex核心概念action(使用到ES6的变量的解构赋值)

    Action Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态. Action 可以包含任意异步操作. 让我们来注册一个简单的 acti ...

  7. ES6之主要知识点(二) 变量的解构赋值。默认值

    引自http://es6.ruanyifeng.com/#docs/destructuring 数组解构赋值 默认值 对象解构赋值 用途 1.数组的解构赋值 let [a, b, c] = [1, 2 ...

  8. es6分享——变量的解构赋值

    变量的解构赋值:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前的写法: var a = 1; var b = 2; es6允许的写法 ...

  9. ES6学习笔记03:变量的解构赋值

    ES6学习笔记03:变量的解构赋值 如果想从复杂数据结构(数组.对象)中获取某一个数据,可能需要大量的遍历操作才能完成.通过解构赋值,这一过程可以得到简化. 1.字符串的解构赋值 其实,Python也 ...

最新文章

  1. [sso]搭建CAS单点服务器
  2. Python(2.7.6) 列表推导式
  3. 信用评分卡模型开发及评估指标
  4. 人脸扫描建模_人脸识别智能锁安全吗?
  5. 选32位 64位 oracle,32位PLSQL配置为64位的Oracle和64位系统
  6. LeetCode题解之Reorder List
  7. QT设计UI:QT模式对话框打开文件
  8. c语言求平衡因子,平衡二叉树(AVL树)的基本操作
  9. CentOS6.8升级gcc到4.8.5总结
  10. 互联网日报 | 社区团购“九不得”新规出台;小米11官宣12月28日发布;长征八号首飞成功...
  11. Asp.net MVC3 WebGrid查询绑定
  12. 如何固定电脑桌面便签 win7便签怎么设置?
  13. Redis 官方推出可视化工具,颜值爆表,功能真心强大!这是不给其他工具活路啊!...
  14. Matlab矩阵操作
  15. VISA 通信command总结
  16. WPS安装后显示系统字体找不到
  17. 百度收录提交 网站快速收录提交方法【附工具】
  18. EPSON TM U220串口打印机乱码
  19. VMware安装winXP SP3专业版+常用软件+正常联网
  20. 机器学习中的概率分布

热门文章

  1. android tcp socket框架_花了一个星期,我终于把RPC框架整明白了
  2. php post 400,post数据时报错:远程服务器返回错误: (400) 错误的请求。
  3. word修改一处另一处自动修改_这么做让word自动记录修改明细,再也不用一个字一个字的核对了...
  4. 线性代数应用于计算机科学例子,为什么计算机科学家们应该了解量子计算?(三):算法棱镜折射出的科学...
  5. c++ int8_t转int_c专题之指针-----什么是指针?
  6. DIoU Loss论文阅读
  7. 渗透测试入门1之信息收集
  8. python 多进程 每个进程做不同功能实例_Python 多进程并发操作中进程池Pool的实例...
  9. go语言结构体作为函数参数,采用的是值传递
  10. WPF的几种布局方式