【JavaScript进阶之旅 ES6篇 第五章】解构赋值深入、隐式转换、函数参数解构、解构本质

本文详细探讨了JavaScript中的解构赋值,包括通过()运算符转换块作用域、模式匹配、函数参数解构以及隐式转换等特性,并通过实例展示了如何使用解构赋值进行变量交换和对象属性匹配。同时,强调了在处理对象属性时的慎用情况,以及在解构过程中可能出现的优先级和匹配规则问题。文章还涉及了字符串、数字、布尔值的隐式转换规则,帮助读者深入理解解构赋值的细节和潜在陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、解构赋值深入

1、通过()运算符将{}产生的块作用域转换为表达式

let a;

// {a} = {a : 1}; // 报错

({a} = {a : 1}); 
console.log(a); // 1

2、模式匹配

let arr = [1, 2, 3],
    obj = {};

[obj.a, obj.b, obj.c] = arr;

console.log(obj); // {a: 1, b: 2, c: 3}

3、用let/var声明:加括号就报错(一句话声明的时候)

let [a] = [1]; 
// let [(a)] = [1]; // 报错
console.log(a); // 1
let {a : b} = {}; 

console.log(b); // undefined
// let {a : b} = {}; // 报错
// let ({a : b}) = {}; // let is not defined
// let {(a): b} = {}; // 报错
// let {a: (b)} = {}; // 报错

console.log(a);

4、函数参数不能加括号

// function foo([z]) { // 报错
//   return z;
// }

// function foo([(z)]) { // 报错
//   return z;
// }

function foo((([z]))) { // 报错
  return z;
}

console.log(foo(1));

5、对象解构数组(数组是特殊的对象)

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

console.log(first, last); // 1 3

6、匹配的规则不同,匹配不成功

[(a)] = [1];
console.log(a); // 1

([a]) = [2]; // 匹配规则不同 规则:() -> [] 应该是:[] -> []
console.log(a); // 报错

7、优先级问题

({a : (b) = {}});  // b的默认值(本身并没有匹配)
console.log(b); // {}

8、[(a.b)] = [3];

var a = {};
[(a.b)] = [3];
console.log(a); // {b: 3}
console.log(b); // 报错 b is not defined

9、({a: obj[a + b]} = {a: 2});

let a = 'x', b = 'y', obj = {};

// {a: obj[a + b]} = {a: 2}; // 会报错

({a: obj[a + b]} = {a: 2}); // 需要加括号变成表达式

console.log(obj); // {xy: 2}

10、利用解构赋值进行 变量交换

let a = 1, b = 2;
[b, a] = [a, b];
console.log(a, b); // 2 1

11、对象匹配允许匹配同源属性(同一个属性)

let {a: x, a: y} = {a: 1};
console.log(x, y); // 1 1
  • 变量的解构就是变量的赋值,本质就是变量的模式匹配
  • 模式匹配可以匹配同一个属性(同源属性)

12、★★ 慎用

var x = 200, y = 300, z = 100;

var obj1 = {
  x: {
    y: 42
  },
  z: {
    y: z // 100
  } 

  // y:  x = { y: 300 }
  // z: { y: }
}

// x = {y : y}}是变量y的默认值;y属性在obj1里没有,是undefined,则找默认值 y是属性,值y从外层找
({y: x = {y: y}} = obj1);   // y: x = {y: 300}

({z: y = {y: z}}) // z: y = {y: 100}

// obj1中有x的属性值 所以 z = x的属性值,即{y: 42} => {y: x} 
({x: z = {y: x}}) // x: z = {y: 42}

console.log(x.y, y.y, z.y); // 300 100 42

二、函数参数解构

function test([a, b]) {
  console.log(a, b);
}
test([1,2]);
test([1]); // 1 undefined
test([]); // undefined undefined
test(); // 报错
function foo({x, y}) {
  console.log(x, y);
}
foo({x: 1,y: 2}); // 1 2
foo({x: 1}); // 1 undefined
foo({}); // undefined undefined
foo(); // 报错
function foo({x = 10} = {}, {y} = {y: 10}) {
  console.log(x, y);
}

foo(); // 10 10
foo({}, {}); // 10 undefined
foo({x: 2}, {y: 3}); // 2 3
  1. 注意这个写法
({x = 10} = {}); // -> x是属性的默认值,这里简写了 {x: x = 10}
({y} = {y: 10}); // -> y也简写了 {y: y}

三、解构的隐式转换

1、字符串进行解构(将字符串原始值隐式转换为String包装类)

const [a, b, c, d] = 'love';
console.log(a, b, c, d); // l o v e

let {length : len} = 'love';
console.log(len); // 4

2、数字进行解构(将数字原始值隐式转换为Number包装类)

let  {toString: s} = 1;
console.log(s === Number.prototype.toString);

3、布尔值进行解构(将布尔值原始值隐式转换为Boolean包装类)

let  {toString: s} = false;
console.log(s === Boolean.prototype.toString);

4、undefined null 不能隐式转换(没有包装类)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值