[ES6] 细化ES6之 -- 变量的解构赋值
变量的解构赋值
解构赋值是什么
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
数组
arr
的0
键对应的值是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);// 大 前 端
数值与布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象.
规则
:
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined
和null
无法转为对象,所以对它们进行解构赋值,都会报错。
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之 -- 变量的解构赋值相关推荐
- ES6阮一峰-----变量的解构赋值学习
1.数组的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前,为变量赋值,只能直接指定值. let a = 1; let b = ...
- ES6新特性_变量的解构赋值---JavaScript_ECMAScript_ES6-ES11新特性工作笔记006
然后我们再看,变量的解构赋值. 可以看到按照一定的模式,从数组和对象中提取数据,以及对对应的变量进行赋值 被称为解构赋值. 可以看到上面 let[xiao,liu,zhao,song]=F4 相当于我 ...
- ES6基础:变量的解构赋值
ES6基础系列之变量的解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构.这种方式的出现大大提高了代码的扩展性 前言 一.数组的解构赋值 二.对象的解构赋值 三.函 ...
- 【ES6】变量的解构赋值
[ES6]变量的解构赋值 一.什么叫解构赋值? 二.解构赋值有哪些分类?写法? 1)对数组的解构赋值 2)对对象的解构赋值 3)对字符串的解构赋值 4)对数值和布尔值的解构赋值 5)对函数参数的解构赋 ...
- ES6的新特性(3)——变量的解构赋值
变量的解构赋值 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). let a = 1; let b = 2; le ...
- Vue2.x—理解vuex核心概念action(使用到ES6的变量的解构赋值)
Action Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态. Action 可以包含任意异步操作. 让我们来注册一个简单的 acti ...
- ES6之主要知识点(二) 变量的解构赋值。默认值
引自http://es6.ruanyifeng.com/#docs/destructuring 数组解构赋值 默认值 对象解构赋值 用途 1.数组的解构赋值 let [a, b, c] = [1, 2 ...
- es6分享——变量的解构赋值
变量的解构赋值:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前的写法: var a = 1; var b = 2; es6允许的写法 ...
- ES6学习笔记03:变量的解构赋值
ES6学习笔记03:变量的解构赋值 如果想从复杂数据结构(数组.对象)中获取某一个数据,可能需要大量的遍历操作才能完成.通过解构赋值,这一过程可以得到简化. 1.字符串的解构赋值 其实,Python也 ...
最新文章
- [sso]搭建CAS单点服务器
- Python(2.7.6) 列表推导式
- 信用评分卡模型开发及评估指标
- 人脸扫描建模_人脸识别智能锁安全吗?
- 选32位 64位 oracle,32位PLSQL配置为64位的Oracle和64位系统
- LeetCode题解之Reorder List
- QT设计UI:QT模式对话框打开文件
- c语言求平衡因子,平衡二叉树(AVL树)的基本操作
- CentOS6.8升级gcc到4.8.5总结
- 互联网日报 | 社区团购“九不得”新规出台;小米11官宣12月28日发布;长征八号首飞成功...
- Asp.net MVC3 WebGrid查询绑定
- 如何固定电脑桌面便签 win7便签怎么设置?
- Redis 官方推出可视化工具,颜值爆表,功能真心强大!这是不给其他工具活路啊!...
- Matlab矩阵操作
- VISA 通信command总结
- WPS安装后显示系统字体找不到
- 百度收录提交 网站快速收录提交方法【附工具】
- EPSON TM U220串口打印机乱码
- VMware安装winXP SP3专业版+常用软件+正常联网
- 机器学习中的概率分布
热门文章
- android tcp socket框架_花了一个星期,我终于把RPC框架整明白了
- php post 400,post数据时报错:远程服务器返回错误: (400) 错误的请求。
- word修改一处另一处自动修改_这么做让word自动记录修改明细,再也不用一个字一个字的核对了...
- 线性代数应用于计算机科学例子,为什么计算机科学家们应该了解量子计算?(三):算法棱镜折射出的科学...
- c++ int8_t转int_c专题之指针-----什么是指针?
- DIoU Loss论文阅读
- 渗透测试入门1之信息收集
- python 多进程 每个进程做不同功能实例_Python 多进程并发操作中进程池Pool的实例...
- go语言结构体作为函数参数,采用的是值传递
- WPF的几种布局方式