ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript - 变量的解构赋值

2021-03-17 20:59:12  阅读:168  来源: 互联网

标签:undefined javascript 解构 let error 默认值 赋值


A:什么是解构赋值?
Q:ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这就是解构。

模式匹配:

let [a, b, c] = [1, 2, 3];

// 相当于
let a = 1;
let b = 2;
let c = 3;

只要等号两边的模式相同,左边的变量就会被赋值给对应的值。


1. 数组的解构赋值

1.1 基本用法

  • 变量取值由它的位置决定
let [x, [[y], z]] = [1, [[2], 3]];

x // 1
y // 2
z // 3
let [x, , y] = [1, 2, 3];

x // 1
y // 3
// ... 剩余操作符,把剩余的内容赋值给y
let [x, ...y] = [1, 2, 3];

x // 1
y // [2, 3]
  • 解构不成功的时候会返回undefined
let [x, y, ...z] = ['a'];

x // 'a'
y // undefined
z // []
  • 不完全解构,但可以解构成功
let [x, y] = [1, 2, 3];

x // 1
y // 2
  • 等号右边不是数组会报错
// error
let [x] = 1;
let [x] = true;
let [x] = NaN;
let [x] = undefined;
let [x] = null;
let [x] = {};
  • 对于Set解构,可以使用解构赋值
let [x, y, z] = new Set(['a', 'b', 'c']);

x // 'a'

如果某种数据结构具有Iterator接口,就可以采用数组形式进行解构赋值。

1.2 默认值

解构赋值允许指定默认值。

let [x = true] = [];

x // true
  • ES6内部使用严格相等运算符(===)判断一个位置是否有值
  • 如果一个数组成员不严格等于undefined,则默认值不生效
let [x, y = 'b'] = ['a'];

x // 'a'
y // 'b'
let [x, y = 'b'] = ['a', 'undefined'];

x // 'a'
y // 'b'

(相等运算符:https://blog.csdn.net/qq_46025031/article/details/114938271

let [x = 1] = [undefined];

x // 1
// 数组中的undefined严格等于undefined,默认值生效
let [x = 1] = [null];

x // null
// 数组中的null不严格等于undefined,默认值不生效
  • 惰性求值:如果默认值为表达式,则表达式是惰性求值的,用到的时候才会求值。
function f() {
	console.log(222);
}

let [x = f()] = [1];

x // 1

因为x能取到值,所以f()不会执行。

  • 默认值可以引用其他解构赋值的变量
let [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] = []  // error,x用到默认值y时y还没有声明

2. 对象的解构赋值

  • 变量必须与属性同名才能取到正确的值
let {a, b, c} = {a: 'aaa', b: 'bbb'};

a // aaa
b // bbb
c // undefined
  • 变量名与属性名不一致
let {a: c} = {a: 'aaa', b: 'bbb'};

c // aaa
  • 对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是后者,而非前者。
let {a: c} = {a: 'aaa', b: 'bbb'};

c // aaa
a // error
// a 是匹配的模式,c 才是变量
  • 嵌套结构
let obj = {
	p: [
		'hello',
		{y: 'world'}
	]
}

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

// p为模式
x // 'hello'
y // 'world'

// 如果想给p赋值
let {p, p: [x, {y}]} = obj;

p // ['hello', {y: 'world'}]
  • 指定默认值
let {x = 3} = {x: undefined};

x // 3
let {x = 3} = {x: null};

x // null
  • 解构失败
let {a} = {b: 'bbb'};

a // undefined

3. 字符串的解构赋值

let [a, b, c, d, e] = 'hello';

a // 'h'
b // 'e'
...
  • length属性
let {length: len} = 'hello';

len // 5

4. 数值和布尔值的解构赋值

  • 如果等号右边是数值和布尔值,会先转为对象
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
  • undefined 和 null 无法转为对象,解构时会报错
let {prop: x} = undefined; // error
let {prop: y} = null; // error

5. 函数参数的解构赋值

function f({x = 0, y = 0} = {}) {
	return [x, y];
}

f({x: 3, y: 8}); // [3, 8]
f({x: 3}); // [3, 0]
f({}); // [0, 0]
f(); // [0, 0]

6. 圆括号问题

6.1 不能使用圆括号的情况

  1. 变量声明语句
let [(a)] = [1]; // error

let {x: (c)} = {}; // error
  1. 函数参数
function f([(z)]) {
	return z;
} // error
  1. 赋值语句的模式
// 整个模式放在圆括号中,报错
({p: a}) = {p: 12};
([a]) = [5];
// 部分模式放在圆括号中,报错
[({p: a}), {x: c}] = [{}, {}];

6.2 可以使用圆括号的情况

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

[(b)] = [3];

({p: (d)} = {});

[(parseInt.prop)] = [3];

7. 用途

  1. 交换变量的值
  2. 从函数返回多个值
  3. 函数参数的定义
  4. 提取JSON数据
  5. 函数参数的默认值
  6. 遍历Map结构
  7. 输入模块的指定方法

标签:undefined,javascript,解构,let,error,默认值,赋值
来源: https://blog.csdn.net/qq_46025031/article/details/114901131

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有