ECMAScript6(ES6)标准之解构赋值语法及应用
2016-12-18 20:53
661 查看
在七种方案解决JavaScript交换两个变量值的问题中
我写的最后一种方案就是用到了ES6的解构赋值语法
下面我来详细说明一下什么是解构赋值
通过解构我们可以让赋值更优雅便捷
当然不仅仅是var,let和const也可以
如果等号两边模式相同
左边变量就会被赋予相应值
所以下面的形式也可以正常赋值
不过我们完全没有必要写这么复杂
如果“…”在等号左边
那么就会把剩余的值合并为一个数组
这个操作符只能写在最后一个变量前面
如果“…”在等号右边
就是把数组展开再赋值
(“…”叫做展开操作符,以后我还会细讲)
也就是解构失败
等号右边少值
与它相对的就是不完全解构
等号左边少值
就会报错
比如说这些情况是不能赋值解构的
下面的情况也是不可以的
它可以拆成
第二个同样不能解构赋值所以会报错
只有当右侧的值严格等于undefined才会使用默认赋值
由于
所以这里foo被赋予null
只有在需要使用默认值的时候
才会去求值
没有的话从左向右解析
这段代码就相当于
注意
如果这里var 换成let就不一样了
这段代码可以看成
由于let声明没有变量提升
所以此时b还未声明就会报错
可以看看这道题
同理如果上面的第四行的var换成let会报错
其实解构赋值不仅仅可以用数组
对象也可以
它们类似的地方就不再赘述了
如果没有找到对应的属性,那就赋予undefined
对于已经声明过的变量要注意
浏览器会报错
因为js引擎把它理解成了代码块
而内部的代码它不认识
解决办法就是加上括号
这样浏览器就可以知道这是一个表达式
但是如果我们想要声明的变量与属性名不同怎么办呢
我们可以使用另一种模式
这相当于声明了a和b变量
同样可以使用默认赋值
字符串被转化为基本包装对象(类数组对象)
所以可以实现
同理这个类数组对象中有length属性
也同样会转化为包装对象
但注意null和undefined没有封装对象
下面的代码会报错
函数参数表面上是一个数组
但在传入参数时,数组参数就被结构成变量 x 和 y
相当于
解构赋值还有很多用途
可以用一个表达式读取整个结构
这种语法可以看成是一种语法糖,受Python语言启发
可以提高我们的编程效率
(语法糖就是这种语法是否存在对语言本身没有影响,只是方便我们开发)
==主页传送门==
我写的最后一种方案就是用到了ES6的解构赋值语法
[a, b] = [b, a]
下面我来详细说明一下什么是解构赋值
数组解构
基本概念
按照一定模式,从数组和对象中提取,对变量进行赋值,称为解构通过解构我们可以让赋值更优雅便捷
// 一般赋值 var a = 1, b = 2, c = 3;
//解构赋值 var [a, b, c] = [1, 2, 3];
当然不仅仅是var,let和const也可以
let arr = [1, 2, 3] const [a, b, c] = arr;
语法本质
实质上这个语法就是一种模式匹配如果等号两边模式相同
左边变量就会被赋予相应值
所以下面的形式也可以正常赋值
var [a, [b, [c, d]]] = [1, [2, [3, 4]]]; console.log(a, b, c, d);//1 2 3 4
不过我们完全没有必要写这么复杂
特殊用法
解构赋值还可以和“…”配合使用如果“…”在等号左边
那么就会把剩余的值合并为一个数组
这个操作符只能写在最后一个变量前面
var [left, ...right] = [1, 2, 3, 4, 5]; console.log(left, right);//1 [2,3,4,5]
如果“…”在等号右边
就是把数组展开再赋值
var arr = [2, 3, 4]; var [a, b, c, d] = [1, ...arr]; console.log(a, b, c, d);//1 2 3 4
(“…”叫做展开操作符,以后我还会细讲)
解构失败与不完全解构
如果没有在匹配中没有对应值,那么它的值就是undefined也就是解构失败
等号右边少值
var [a, b, c] = [1, 2]; console.log(a, b, c);//1 2 undefined
与它相对的就是不完全解构
等号左边少值
var [a, b] = [1, 2, 3]; console.log(a, b);//1 2
错误解构
如果等号右边不是数组(不是可遍历解构)就会报错
比如说这些情况是不能赋值解构的
var [foo] = 1/true/NaN/undefined/null/{};
下面的情况也是不可以的
var [a, [b]] = [1, 2];
它可以拆成
var a = 1;和
var [b] = 2;
第二个同样不能解构赋值所以会报错
默认赋值
可以使用下面这种语法实现默认的赋值var [foo = 1] = []; console.log(foo); //1
只有当右侧的值严格等于undefined才会使用默认赋值
var [foo = 1] = [null]; console.log(foo); //null
由于
null !== undefined
所以这里foo被赋予null
惰性赋值
惰性赋值说的是默认赋值的机制只有在需要使用默认值的时候
才会去求值
function foo(){ alert(' '); return 123; }
var [a = foo()] = [1]; //不弹窗 console.log(a); //1
var [a = foo()] = []; //弹窗 console.log(a); //123
解构顺序
解构赋值首先会看右边有没有与之对应的值没有的话从左向右解析
var [a = 1, b = a] = []; console.log(a, b); //1 1
这段代码就相当于
var a = 1; var b = a;
var [a = b, b = 1] = []; console.log(a, b); //undefined 1
注意
如果这里var 换成let就不一样了
let [a = b, b = 1] = []; console.log(a, b); //报错
这段代码可以看成
let a = b; let b = 1;
由于let声明没有变量提升
所以此时b还未声明就会报错
可以看看这道题
var [x1 = 1, y1 = x1] = []; var [x2 = 1, y2 = x2] = [2]; var [x3 = 1, y3 = x3] = [1,2]; var [x4 = y4, y4 = 1] = []; console.log(x1,y1);//1 1 console.log(x2,y2);//2 2 console.log(x3,y3);//1 2 console.log(x4,y4);//undefined 1
同理如果上面的第四行的var换成let会报错
对象解构
上面我们通过数组的形式了解了解构赋值其实解构赋值不仅仅可以用数组
对象也可以
它们类似的地方就不再赘述了
基本用法
对象的解构赋值是按照属性名(键)决定的如果没有找到对应的属性,那就赋予undefined
var {foo, bar, foobar} = { foo: 1, bar: 2 } console.log(foo, bar, foobar);//1 2 undefined
对于已经声明过的变量要注意
var a; {a} = {a: 1}; //错误
浏览器会报错
因为js引擎把它理解成了代码块
而内部的代码它不认识
解决办法就是加上括号
这样浏览器就可以知道这是一个表达式
var a; ({a} = {a: 1});
但是如果我们想要声明的变量与属性名不同怎么办呢
我们可以使用另一种模式
var {foo: a, bar: b, foobar: c = 100} = { foo: 1, bar: 2 } console.log(a, b, c);//1 2 100
这相当于声明了a和b变量
同样可以使用默认赋值
字符串解构赋值
var [a, b, c, d, e] = 'hello'; console.log(a, b, c, d, e); //h e l l o
字符串被转化为基本包装对象(类数组对象)
所以可以实现
var {length : len} = 'hello'; console.log(len); //5
同理这个类数组对象中有length属性
基本值解构赋值
如果等号右边是数字或者布尔值也同样会转化为包装对象
let {toString: a} = 123; let {toString: b} = true; console.log( a === Number.prototype.toString); //true console.log( b === Boolean.prototype.toString); //true
但注意null和undefined没有封装对象
下面的代码会报错
let {toString: x } = undefined; //错误
let {toString: y } = null; //错误
函数参数的结构赋值
function add([x, y]) { return x + y; } console.log(add([1, 2]));
函数参数表面上是一个数组
但在传入参数时,数组参数就被结构成变量 x 和 y
相当于
var [x, y] = [1, 2]
function foo({x = 0, y = 0} = {}){ console.log([x, y]); } foo({x: 1,y: 2}); //[1, 2] foo({x: 1}); //[1, 0] foo({}); //[0, 0] foo(); //[0, 0]
function bar({x, y} = {x: 0, y: 0}){ console.log([x, y]); } bar({x: 1,y: 2}); //[1, 2] bar({x: 1}); //[1, undefined] bar({}); //[undefined, undefined] bar(); //[0, 0]
解构赋值的应用
除了交换变量以外解构赋值还有很多用途
函数多值返回
function demo(){ return [1, 2, 3]; } var [a, b, c] = demo();
函数定义参数
function demo({a, b, c}){ ... } demo({a: 1, b: 2, c: 3});
提取JSON数据
var jsonData= { id: 66, status: 'OK', data: [123, 456] } let {id, status, data:number} = jsonData;
总结
解构语法可以快速从数组或对象中提取变量可以用一个表达式读取整个结构
这种语法可以看成是一种语法糖,受Python语言启发
可以提高我们的编程效率
(语法糖就是这种语法是否存在对语言本身没有影响,只是方便我们开发)
==主页传送门==
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- 只需四个步骤几行代码,即可快速实现直播弹幕功能
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- JavaScript 基础、进阶以及 Ubuntu 系统中的 JavaScript 开发调试工具
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 设计模式---状态模式在web前端中的应用
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法