解构赋值

解构赋值

本质: 模式匹配,只要两边的模式相同。左边的变量就会被赋予对应的值

  1. 数组的解构赋值

数组的元素是按下标排列的,变量的取值由他的位置所决定

let [a, c, d] = [1, 2, 3];
let [e, [f, [j]]] = [1, [2, [3]]];
  1. 不完全解构
let [o] = []; // undefined
let [bar, foo] = [1]; // 1 , undefined
  1. 嵌套数组解构
let [ , , third] = ["foo", "bar", "baz"]; //  third = baz
let [x, y, ...z] = ['a']; // a, undefined, []
  1. 默认值

在解构赋值时是允许指定默认值
ES6内部使用的是严格全等运算符, 判断一个位置是否有值,所以,当其中某一个数组成员必须全等undefined才会生效默认值(undefined就会触发函数参数的默认值)

let [foo] = []; // undefined
let [foo = false] = []; // false

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

let [x = 1] = [null]; // 不与undefined全等  null

  1. 对象的解构赋值**

对象的变量取值必须与属性同名,才能取到正确的值
内部机制: 先找到同名属性,然后再赋给对应的变量
取不到则说明解构失败,变量的值等于undefined
嵌套解构对象的时候需要注意嵌套规则,如果出现父属性都不存在的情况下, 还继续取子属性则会报错

let {foo} = {bar: 'bar'};  // foo: undefined

// 报错
let {foo: {bar}} = {baz: 'baz'};
  1. 变量重命名**

foo是匹配的模式,foz才是变量。真正被赋值的是变量foz

let {foo: foz} = {foo: 'foo'}; // foz: 'foo'
  1. 已声明的变量不能作为解构赋值的变量

JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误

// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
  1. 数组是一个特殊对象,因此可以对数组进行对象属性的解构

数组arr的0键对应的值是1,[arr.length - 1]就是2键,对应的值是3。方括号这种写法,属于“属性名表达式”

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3
  1. 函数参数的解构赋值**
function add([x, y]){
  return x + y;
}

add([1, 2]); // 3


// 使用默认参数
function 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]

问题:
圆括号的问题: 圆括号有可能会导致解构的表达式有歧义,所以需要慎用

  1. 变量声明语句的时候不能用括号
let {(x): c} = {};
let { o: ({ p: p }) } = { o: { p: 2 } };
  1. 函数参数也属于变量声明,因此不能带有圆括号
// 报错
function f([(z)]) { return z; }
// 报错
function f([z,(x)]) { return x; }
  1. 赋值语句的模式
({ p: d }) = { p: 42 };
([a]) = [5];
  1. 可使用圆括号的时候

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

[(b)] = [4]; // 正确
({ k: (d) } = {}); // 正确
[(parse.prop)] = [3]; // 正确

用途:

  1. 变量值的交换
  2. 函数参数的提取及定义,默认值的定义
  3. 函数及模块的抛出值,引入模块(提取所需的方法)
  4. 提取 JSON 数据,解构赋值对提取 JSON 对象中的数据

你可能感兴趣的:(解构赋值)