ES6学习篇二变量的解构赋值

数组的解构赋值

基本语法与解构结果说明

正常解构赋值与结果展示

						let x = {
							a: 1
						};
						const [a, b, c] = [{
								a: 1,
								b: 2
							},
							[1, 2, 3],
							function() {
								console.log(1111112)
							}
						];
						console.log(a); //{a:1,b:2}
						console.log(b); //[1,2,3]
						c(); //1111112

解构不成功

不会报错,undefined

			let [foo1] = [];
			let [bar, foo2] = [1];
			console.log("foo1", foo1); //undefined
			console.log("bar", bar); //1
			console.log("foo2", foo2); //undefined

不完全解构

左边只能匹配右边部分,

			let [x1, x2] = [1, 2, 3];
			console.log(x1); //1
			console.log(x2); //2

解构报错

转换成对象后没有Iterator接口

						let [foo3] = 1;
						let [foo4] = false;
						let [foo5] = NaN;
						let [foo6] = undefined;
						let [foo7] = null;
						let [foo8] = {};

Set结构也可以使用数组的解构赋值

只要具备Iterator接口,就可以采用数组形式的解构赋值

						let [x,y,z] = new Set(['a','a','c']);
						console.log(x);  // a
						console.log(y);  // c
						console.log(z);  //undefined

默认值

解构赋值允许指定默认值

			let [defaultA = 'true',defaultB] = [,'a'];
			console.log(defaultA,defaultB); //true,a

只有当所赋值为严格意义上的undefined时,默认值才会生效

			let [defaultUndefined1,defaultUndefined2 = 1] = [2,null];
			console.log(defaultUndefined1);  // 2
			console.log(defaultUndefined2);  // null

默认值为一个表达式

			function f() {
				console.log("blabla");
			}
			let [expressX = f()] = [1];
			console.log(expressX); // 1,函数未执行

对象的解构赋值

基本语法

			let {first, second, middle, last} = {first:'莫', middle: '笑', last: '忘'};
			console.log(first); //莫
			console.log(middle); //笑
			console.log(last); //忘
			console.log(second); //undefined

对象的属性名无次序,没有对应属性名可匹配,则赋值为undefined;
如果变量名与属性名不一致,形式如下:

			let {first: firstName} = {first:'莫'};
			console.log(firstName); //莫
			console.log(first); //报错

在以上解构赋值代码中,first为匹配的模式,firstName才是要被赋值的变量;
嵌套对象的解构赋值:

			let obj = {
				p: [
					'Hello',
					{
						y: 'World'
					}
				]
			};

			let {
				p: [x, {
					y
				}]
			} = obj;
			console.log(x);  // hello
			console.log(y);  //world

如果希望p也作为变量赋值:

let { p, p: [x, { y }] } = obj;

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

let {name: {first}} = {gender: 'female'}; //报错

对象的解构赋值可以取到继承的属性;可以指定默认值,生效的条件为对象的属性值严格等于undefined;
如果将一个已经声明的变量用于结构赋值,需注意:

// 错误的写法
let x;
{x} = {x: 1};

原因:js引擎将{x}理解成一个代码块,所以发生语法错误,所以不将{}防砸行首:

let x;
({x} = {x: 1});

解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式,虽毫无意义,但是合法。也可以对数组进行对象属性的解构:

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3

字符串的解构赋值

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

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值:

let {length : len} = 'hello';
len // 5

数值和布尔值的解构赋值

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

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

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

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

函数参数的解构赋值

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]

圆括号问题

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];
[({ p: a }), { x: c }] = [{}, {}];

可以使用圆括号的情况

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

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

以上特征1:赋值语句;2:圆括号不属于模式的一部分

用途

交换变量的值

简便直观

			let x = 1;
			let y = 2;

			[x, y] = [y, x];
			console.log(x); //2
			console.log(y); //1

从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便

// 返回一个数组

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

函数参数的定义

我怎么觉得这个用途没甚意义呢

// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

提取JSON数据

这个还蛮方便的

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]

函数参数的默认值

可以避免在函数体内再对参数进行默认赋值等

function ({a=1,b=2} = {}){
//BLABLA
}

遍历Map结构

任何部署了 Iterator 接口的对象,都可以用for…of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。

const 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) {
  // ...
}

输入模块的指定方法

加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰
(这个好像很少用啊,像我现在是这样)

const { SourceMapConsumer, SourceNode } = require("source-map");

数组的解构赋值

基本语法与解构结果说明

正常解构赋值与结果展示

						let x = {
							a: 1
						};
						const [a, b, c] = [{
								a: 1,
								b: 2
							},
							[1, 2, 3],
							function() {
								console.log(1111112)
							}
						];
						console.log(a); //{a:1,b:2}
						console.log(b); //[1,2,3]
						c(); //1111112

解构不成功

不会报错,undefined

			let [foo1] = [];
			let [bar, foo2] = [1];
			console.log("foo1", foo1); //undefined
			console.log("bar", bar); //1
			console.log("foo2", foo2); //undefined

不完全解构

左边只能匹配右边部分,

			let [x1, x2] = [1, 2, 3];
			console.log(x1); //1
			console.log(x2); //2

解构报错

转换成对象后没有Iterator接口

						let [foo3] = 1;
						let [foo4] = false;
						let [foo5] = NaN;
						let [foo6] = undefined;
						let [foo7] = null;
						let [foo8] = {};

Set结构也可以使用数组的解构赋值

只要具备Iterator接口,就可以采用数组形式的解构赋值

						let [x,y,z] = new Set(['a','a','c']);
						console.log(x);  // a
						console.log(y);  // c
						console.log(z);  //undefined

默认值

解构赋值允许指定默认值

			let [defaultA = 'true',defaultB] = [,'a'];
			console.log(defaultA,defaultB); //true,a

只有当所赋值为严格意义上的undefined时,默认值才会生效

			let [defaultUndefined1,defaultUndefined2 = 1] = [2,null];
			console.log(defaultUndefined1);  // 2
			console.log(defaultUndefined2);  // null

默认值为一个表达式

			function f() {
				console.log("blabla");
			}
			let [expressX = f()] = [1];
			console.log(expressX); // 1,函数未执行

对象的解构赋值

基本语法

			let {first, second, middle, last} = {first:'莫', middle: '笑', last: '忘'};
			console.log(first); //莫
			console.log(middle); //笑
			console.log(last); //忘
			console.log(second); //undefined

对象的属性名无次序,没有对应属性名可匹配,则赋值为undefined;
如果变量名与属性名不一致,形式如下:

			let {first: firstName} = {first:'莫'};
			console.log(firstName); //莫
			console.log(first); //报错

在以上解构赋值代码中,first为匹配的模式,firstName才是要被赋值的变量;
嵌套对象的解构赋值:

			let obj = {
				p: [
					'Hello',
					{
						y: 'World'
					}
				]
			};

			let {
				p: [x, {
					y
				}]
			} = obj;
			console.log(x);  // hello
			console.log(y);  //world

如果希望p也作为变量赋值:

let { p, p: [x, { y }] } = obj;

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

let {name: {first}} = {gender: 'female'}; //报错

对象的解构赋值可以取到继承的属性;可以指定默认值,生效的条件为对象的属性值严格等于undefined;
如果将一个已经声明的变量用于结构赋值,需注意:

// 错误的写法
let x;
{x} = {x: 1};

原因:js引擎将{x}理解成一个代码块,所以发生语法错误,所以不将{}防砸行首:

let x;
({x} = {x: 1});

解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式,虽毫无意义,但是合法。也可以对数组进行对象属性的解构:

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3

字符串的解构赋值

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

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值:

let {length : len} = 'hello';
len // 5

数值和布尔值的解构赋值

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

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

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

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

函数参数的解构赋值

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]

圆括号问题

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];
[({ p: a }), { x: c }] = [{}, {}];

可以使用圆括号的情况

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

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

以上特征1:赋值语句;2:圆括号不属于模式的一部分

用途

交换变量的值

简便直观

			let x = 1;
			let y = 2;

			[x, y] = [y, x];
			console.log(x); //2
			console.log(y); //1

从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便

// 返回一个数组

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

函数参数的定义

我怎么觉得这个用途没甚意义呢

// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

提取JSON数据

这个还蛮方便的

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]

函数参数的默认值

可以避免在函数体内再对参数进行默认赋值等

function ({a=1,b=2} = {}){
//BLABLA
}

遍历Map结构

任何部署了 Iterator 接口的对象,都可以用for…of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。

const 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) {
  // ...
}

输入模块的指定方法

加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰
(这个好像很少用啊,像我现在是这样)

const { SourceMapConsumer, SourceNode } = require("source-map");

猜你喜欢

转载自blog.csdn.net/weixin_42153877/article/details/88963579