参考文档:
ES6
数组的解构赋值
1.原来的直接赋值,可以写成 var [a, b, c] = [1, 2, 3]
,例如:
let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3
let [ , , third] = [“foo”, “bar”, “baz”]; third // “baz”
let [x, , y] = [1, 2, 3]; x // 1 y // 3
let [head, …tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4]
let [x, y, …z] = [‘a’]; x // “a” y // undefined z // []
2.当解构不成功时,变量值等于undefined,例如:
var [foo] = [];
var [bar, foo] = [1];
3.不完全解构,只匹配解构一部分数据,例如:
let [x, y] = [1, 2, 3]; x // 1 y // 2
let [a, [b], d] = [1, [2, 3], 4]; a // 1 b // 2 d // 4
4.解构赋值适用于var,let和const,例如:
var [v1, v2, …, vN ] = array;
let [v1, v2, …, vN ] = array; const
[v1, v2, …, vN ] = array;
5.对set结构,也能用数组解构赋值,例如:
let [x, y, z] = new Set([“a”, “b”, “c”]); x // “a”
6.只要某种数据结构具有iterator接口,都可以采用数组的形式解构赋值,例如:
1
2
3
4
5
6
7
8
9
10
11function* fibs() { var a = 0; var b = 1; while (true) { yield a; [a, b] = [b, a + b]; } } var [first, second, third, fourth, fifth, sixth] = fibs(); console.log(first, second, third, fourth, fifth, sixth); // 0,1,1,2,3,5
默认值
1.解构赋值允许指定默认值,例如:
1
2
3
4
5
6
7var [foo = true] = []; console.log(foo)// true let [x, y = 'b'] = ['a']; console.log(x,y) // x='a', y='b' let [mm, nn = 'b'] = ['a', undefined]; console.log(mm,nn) // mm='a', nn='b'
2.如果一个数组成员不严格等于undefined,默认值是不会生效的,例如:
1
2
3
4
5
6
7var [x = 1] = [undefined]; console.log(x) //1 var [y = 1] = [null]; console.log(y) //null var [m = 1] = []; console.log(m) //1
3.若默认值是一个表达式,则该表达式是惰性的,只有再用到的时候才会求值,例如:
1
2
3
4
5
6function f() { console.log('aaa'); } let [x = f()] = [1]; console.log(x) //1
等价于
1
2
3
4
5
6
7
8let x; if ([1][0] === undefined) { x = f(); } else { x = [1][0]; } console.log(x) //1
4.默认值也可以解构其他变量,但前提该变量必须已经声明,例如:
1
2
3
4
5
6
7
8let [x = 1, y = x] = []; // x=1; y=1 let [x = 1, y = x] = [2]; // x=2; y=2 let [x = 1, y = x] = [1, 2]; // x=1; y=2 let [x = y, y = 1] = []; // ReferenceError
对象的解构赋值
1.解构还可以用于对象,例:
1
2
3
4var { foo, bar } = { foo: "aaa", bar: "bbb" }; // ReferenceError console.log(foo,bar) //aaa,bbb
2.对象的解构不按照位置顺序决定,按照他的属性名决定,例:
1
2
3
4
5var { bar, foo } = { foo: "aaa", bar: "bbb" }; console.log(foo,bar) //aaa,bbb var { baz } = { foo: "aaa", bar: "bbb" }; console.log(baz) //undefined
3.若等号左边与等号右边属性名不一致,应按照如下写法:
1
2
3
4
5
6
7var { foo: baz } = { foo: 'aaa', bar: 'bbb' }; console.log(baz) //aaa let obj = { first: 'hello', last: 'world' }; let { first: f, last: l } = obj; console.log(f) //hello console.log(l) //world
4.对象的解构赋值是先找到同名属性,然后再赋值给其他变量,例:
1
2
3
4var { foo: baz } = { foo: "aaa", bar: "bbb" }; console.log(baz) //aaa console.log(foo) //ReferenceError
5.变量和声明是一体的,一旦赋值的变量以前声明过,就会报错,例:
1
2
3
4
5
6
7
8
9
10
11let foo; let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo" let baz; let {bar: baz} = {bar: 1}; // SyntaxError: Duplicate declaration "baz" //let命令下面一行的圆括号是必须的,否则会报错。 //因为解析器会将起首的大括号,理解成一个代码块,而不是赋值语句。 let foo; ({foo} = {foo: 1}); // 成功 let baz; ({bar: baz} = {bar: 1}); // 成功
6.和数组一样,解构也能用在嵌套解构的对象中,例:
1
2
3
4
5
6
7
8
9
10
11var obj = { p: [ 'Hello', { y: 'World' } ] }; var { p: [x, { y }] } = obj; //这时p是模式,不是变量,因此不会被赋值。 console.log(x) //Hello console.log(y) //World
同例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14var node = { loc: { start: { line: 1, column: 5 } } }; var { loc: { start: { line }} } = node; console.log(node) //{"loc":{"start":{"line":1,"column":5}}} console.log(line) //1 console.log(loc) //Uncaught ReferenceError: loc is not defined console.log(start) //>Uncaught ReferenceError: start is not defined
7.嵌套赋值,例:
1
2
3
4
5
6let obj = {}; let arr = []; ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true }); console.log(obj) //{"prop":123} console.log(arr) // [true]
8.对象解构也能有默认值,对象的属性值严格等于undefined,例:
1
2
3
4
5
6
7
8
9
10
11
12var {x = 3} = {}; x // 3 var {x, y = 5} = {x: 1}; x // 1 y // 5 var {x:y = 3} = {}; y // 3 var {x:y = 3} = {x: 5}; y // 5 var { message: msg = 'Something went wrong' } = {}; msg // "Something went wrong" var {x = 3} = {x: undefined}; x // 3 var {x = 3} = {x: null}; x // null
9.数组的本质是特殊的对象,因此可以对数组进行对象属性的解构,例:
1
2
3
4
5var arr = [1, 2, 3]; var {0 : first, [arr.length - 1] : last} = arr; first // 1 last // 3
字符串的解构赋值
1.字符串也可以解构赋值,例:
1
2
3
4
5
6
7const [a, b, c, d, e] = 'hello'; a // "h" b // "e" c // "l" d // "l" e // "o"
2.字符串有length属性,因此可以对起解构,例:
1
2
3let {length : len} = 'hello'; len // 5
数值和布尔值的解构赋值
1.解构赋值时,如果等号右边是数值或布尔值,则先转为对象。例:
1
2
3
4
5let {toString: s} = 123; s === Number.prototype.toString // true let {toString: s} = true; s === Boolean.prototype.toString // true
2.由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。例:
1
2
3let { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError
函数参数的解构赋值
1.函数的参数也能用解构赋值,例:
1
2
3
4
5function add([x, y]){ return x + y; } console.log(add([1, 2])) // 3
2.对于函数内部的代码来说,它们能感受到的参数就是x和y。例:
1
2console.log([[1, 2], [3, 4]].map(([a, b]) => a + b)) // [3,7]
3.函数参数的解构也可以使用默认值。例:
1
2
3
4
5
6
7
8function move({x = 0, y = 0} = {}) { return [x, y]; } move({x: 3, y: 8}); // [3, 8] move({x: 3}); // [3, 0] move({}); // [0, 0] move(); // [0, 0]
4.undefined就会触发函数参数的默认值。例:
1
2
3[1, undefined, 3].map((x = 'yes') => x); // [ 1, 'yes', 3 ]
圆括号问题
ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号。
不使用圆括号的情况
1.变量声明语句中,模式不能使用圆括号。例:
1
2
3
4
5
6
7
8// 全部报错 var [(a)] = [1]; var {x: (c)} = {}; var ({x: c}) = {}; var {(x: c)} = {}; var {(x): c} = {}; var { o: ({ p: p }) } = { o: { p: 2 } };
2.函数参数中,模式不能带有圆括号。例:
1
2
3// 报错 function f([(z)]) { return z; }
3.赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中。
1
2
3
4
5
6// 全部报错-》将整个模式放在圆括号之中,导致报错。 ({ p: a }) = { p: 42 }; ([a]) = [5]; // 报错-》将嵌套模式的一层,放在圆括号之中,导致报错。 [({ p: a }), { x: c }] = [{}, {}];
使用圆括号的情况
使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号。例:
1
2
3
4[(b)] = [3]; // 正确 ({ p: (d) } = {}); // 正确 [(parseInt.prop)] = [3]; // 正确
用途
1.交换变量的值。写法不仅简洁,而且易读,语义非常清晰。
1
2[x, y] = [y, x];
2.从函数返回多个值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 返回一个数组 function example() { return [1, 2, 3]; } var [a, b, c] = example(); // 返回一个对象 function example() { return { foo: 1, bar: 2 }; } var { foo, bar } = example();
3.函数参数的定义
1
2
3
4
5
6
7// 参数是一组有次序的值 function f([x, y, z]) { ... } f([1, 2, 3]); // 参数是一组无次序的值 function f({x, y, z}) { ... } f({z: 3, y: 2, x: 1});
4.提取JSON数据
1
2
3
4
5
6
7
8var jsonData = { id: 42, status: "OK", data: [867, 5309] }; let { id, status, data: number } = jsonData; console.log(id, status, number);
5.函数参数的默认值
1
2
3
4
5
6
7
8
9
10
11
12jQuery.ajax = function (url, { async = true, beforeSend = function () {}, cache = true, complete = function () {}, crossDomain = false, global = true, // ... more config }) { // ... do stuff };
6.遍历Map结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//任何部署了Iterator接口的对象,都可以用for...of循环遍历。 var map = new Map(); map.set('first', 'hello'); map.set('second', 'world'); for (let [key, value] of map) { console.log(key + " is " + value); } // first is hello // second is world //如果只想获取键名,或者只想获取键值,可以写成下面这样 // 获取键名 for (let [key] of map) { // ... } // 获取键值 for (let [,value] of map) { // ... }
7.输入模块的指定方法,例:
1
2const { SourceMapConsumer, SourceNode } = require("source-map");
最后
以上就是纯情小伙最近收集整理的关于ES6笔记:变量的解构赋值数组的解构赋值默认值对象的解构赋值字符串的解构赋值数值和布尔值的解构赋值函数参数的解构赋值圆括号问题用途的全部内容,更多相关ES6笔记:变量内容请搜索靠谱客的其他文章。
发表评论 取消回复