ES6解构赋值
来源:互联网 发布:防水运动鞋 知乎 编辑:程序博客网 时间:2024/06/04 19:29
数组的解构赋值
ES6中允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这称为解构赋值,在ES5中为变量赋值,只能直接指定值
首先,有几个简单的例子
1)左边和右边“模式匹配”,完全解构,按照对应的位置,为变量赋值
let [a, b, c] = [1, 2, 3];console.log(a, b, c); //1 2 3//略微复杂一点的嵌套,但是也是模式匹配的let [foo, [[bar], baz]] = [1, [[2], 3]];console.log(foo, bar, baz); //1 2 3
babel编译后的代码
"use strict";var a = 1;var b = 2;var c = 3;console.log(a, b, c); //1 2 3
发现“模式匹配”的情况下,编译出的代码就是单个定义的
2)左边和右边“非模式匹配”,部分解构
let [,,third] = [3, 5, 7];console.log(third); //7//和扩展运算符一同使用let [head, ...tail] = [1, 2, 3, 4];console.log(head, tail);// 1 [2, 3, 4]let [x, y, ...z] = [1];console.log(x, y, z);// 1 undefined []
解构不成功,变量的就等于undefined,因为有扩展运算符,所以z的值为空数组
bable后的代码
第一段的话,就是定义了个数组,赋值为右边的值,然后,给指定变量赋予指定的值
"use strict";var _ref = [3, 5, 7];var third = _ref[2];console.log(third); //7
第二段的话,是含有扩展运算符的,就是单独定义
"use strict";var head = 1;var tail = [2, 3, 4];console.log(head, tail);
第三段的话,可以看作是前面两个的综合
"use strict";var _ref = [1];var x = _ref[0];var y = _ref[1];var z = _ref.slice(2);console.log(x, y, z); // 1 undefined []
需要注意的地方:如果等号右边的不是数组(不是可遍历的结构)就会报错,当然只要转为带有Iterator接口的对象就好了
let [re] = 1;
let [x, y, z] = new Set([1, 2, 4]);
3)默认值的情况
let [x = 1] = [];console.log(x); // 1
当默认值和右边同时有值的话,那么取的是等号右边的[]
中的值
let [y, z = 2] = [3, 4];console.log(z); //4let [r = 99] = [null];console.log(r); //null
当为undefined的时候取得就是默认值
let [r = 99] = [undefined];console.log(r);
对象的解构赋值
1)简单的情况
let {foo, bar} = {bar: 'aaa', foo: 'bbb'};console.log(foo, bar);// bbb aaa
对象的属性是没有次序的,变量必须和属性同名,才能取得到正确的值,babel后的代码如下
'use strict';var _bar$foo = { bar: 'aaa', foo: 'bbb' };var foo = _bar$foo.foo;var bar = _bar$foo.bar;console.log(foo, bar); // bbb aaa
当没有同名属性的时候,就等于undefined
let {brr} = {bar : 999};console.log(brr); // undefined
对象赋值的机制是,先找到同名属性,然后再赋给对应的变量,真正被赋值的是后者,而不是前者
let {foo: bar} = {bar: 'aaa', foo: 'bbb'};console.log( bar); // bbb
前面的代码可以看做是下面的简写方式
let {foo:foo, bar:bar} = {bar: 'aaa', foo: 'bbb'};console.log( bar); //aaa
2)多层嵌套的方式
let obj = { p: [ 'hello', {y : 'world'} ]};let {p, p: [x, {y}]} = obj;console.log(p, x, y); //[ 'hello', { y: 'world' } ] 'hello' 'world'
这段代码,建议通过自己的理解,写出等号左边的部分,如果写出来了,就说明对于对象和数组的结构赋值有了比较清晰的认识,数组的左边定义变量的形式是[]
,对象的左边定义变量的形式是{}
const node = { loc: { start : { line: 1, column: 5 } }};let {loc, loc: {start : {line, column}}} = node;console.log(loc, line, column);// { start: { line: 1, column: 5 } } 1 5
3)默认值的情况,和数组的是类似的,这里就不在赘述
4)已经声明的变量用于解构赋值的情况
//会出现错误,js引擎会将{x}理解为一个代码块,从而发生了语法错误let x;{x} = {x: 1};
正确的写法,需要加一对括号
let x;({x} = {x: 1});
babel后的代码
"use strict";var x = undefined;var _x = { x: 1 };x = _x.x;_x;
5)几个特殊的用法
将现有对象的方法,赋值给某个变量
let {sin, cos, tan} = Math;
数组也可以进行对象属性的解构
let arr = [1, 2, 3];let {0: first, [arr.length-1]: last} = arr;console.log(first, last); // 1 3
字符串的解构赋值
const [a, b, c, d, e] = "hello";console.log(a, b, c, d, e);// h e l l o
函数参数的结构赋值
1)不含默认值
function add([x, y]) { return x + y;}var res = add([1, 2]);console.log(res);// 3
babel后的结果
"use strict";var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _ arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })();function add(_ref) { var _ref2 = _slicedToArray(_ref, 2); var x = _ref2[0]; var y = _ref2[1]; return x + y;}var res = add([1, 2]);console.log(res);
大概看了一下_slicedToArray这个函数,感觉它的作用就是产生真的数组
[[1, 2], [3, 4]].map(([a, b]) => { console.log(a + b);});// 3, 7
2)包含默认值的情况
为变量x和y指定默认值,函数的参数是一个对象,通过对这个对象进行解构,得到变量x和y的值,解构失败的情况下,x和y等于默认值
function move({x=0, y=0} = {}) { return [x, y];}var res = move({x: 3, y: 4});console.log(res); //[3, 4]console.log(move());// [0, 0]console.log(move({}));// [0, 0]
为函数参数指定默认值
function move({x, y} = {x: 1, y : 2}) { return [x, y];}var res = move({x: 3, y: 4});console.log(res); //[ 3, 4 ]console.log(move());// [ 1, 2 ]console.log(move({}));// [ undefined, undefined ]
undefined可以触发函数的默认值
[1, undefined, 3].map((x= 88) => console.log(x)); // 1 88 3
用途
1)交换两个变量的值
let x = 1;let y = 2;[x, y] = [y, x];console.log(x, y); // 2 1
2)从函数中返回多个值
//返回数组function example() { return [3, 4, 5];}let [a, b, c] = example();console.log(a, b, c);
//返回对象function test() { return { foo : 1, bar : 2 };}let {foo, bar} = test();console.log(foo, bar);
- 【ES6系列】解构赋值
- ES6 destructuring 解构赋值
- es6 chapter3 解构赋值
- ES6 解构赋值用途
- ES6:解构赋值
- ES6 解构赋值
- 【es6】解构赋值
- es6-变量解构赋值
- ES6-变量解构赋值
- ES6变量解构赋值
- ES6解构赋值详解
- ES6解构赋值
- ES6之解构赋值
- ES6之-解构赋值
- ES6之解构赋值
- ES6解构赋值
- ES6:解构赋值
- es6语法-解构赋值
- DELPHI高性能大容量SOCKET并发(四):粘包、分包、解包
- python_csv模块学习
- 北漂的日常
- Android开发之ListView选中某行后改变其背景色
- FTP常用命令以及客户端介绍
- ES6解构赋值
- Luogu 1186(SPFA)
- Oracle删除表空间tablespace
- js控件的操作,以后学到的所有js控件都放到这里
- ubuntu 下编译android libjpeg-turbo-1.5.2
- POJ 3304:Segments 计算几何 是否有直线与所有线段相交
- 深入剖析,自己实现Butter knife
- leetcode 46. Permutations
- jquery-confrim使用