ES6-变量解构

本文详细介绍了ES6中的解构赋值,包括数组和对象的解构,以及默认值使用、函数参数的解构赋值。解构允许按照模式从数组和对象中提取值,简化了变量赋值的过程。例如,解构赋值可以用于函数参数,当数组或对象传入时,会自动解析并赋值给对应的变量。同时,文章提到了对象解构时,即使属性名不一致,通过模式名称也能正确赋值。

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

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

以前这样定义变量

let a = 1;
let b = 2;
let c = 3;
console.log(a, b, c);

ES6这样定义:

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

二者结果相等。


只要等号两边的模式结构相等,值就能一一对应上,如果模式结构不相等,则按照顺序匹配对应,Such as:

let [x, y] = [1, 2, 3];
let [a, [b], c] = [5, [6, 7], 8];
console.log("x:" + x, "y:" + y, "a:" + a, "b:" + b, "c:" + c);

结果

x:1 y:2 a:5 b:6 c:8

按照顺序对应即可,对应不上的值会报undefined。

解构赋值还可以是对象,只要数据结构具有iterator接口,都可采用数组进行解构赋值。

let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

前5个例子转为对象之后并没有实现iterator接口,而最后一个例子本身便不具备Iterator接口。

function* fibs() {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

let [first, second, third, fourth, fifth, sixth] = fibs();


functon* fibs其实是定义 一个数组,每个值都是a(yield语句本身是没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield语句的返回值),而数组的长度由解构内容决定,这里每次a b的值如下:

第一次遇到yield直接暂停,所以  a = 0;

第二次:[1, 1]

第三次:[1, 2]

第四次:[2, 3]

第五次 :[3, 5]

第六次: [5, 8]

而这个函数返回的始终是值为a 的数组,也就是返回[1, 1, 2, 3, 5]

大彻大悟,在阳锅的指导下




默认值使用
let [foo = true] = [];
foo // true

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

只有当数组内的成员严格等于(===)undefined的时候才会使用默认值,如果是null的话值为null而不是为默认值。

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null


对象的结构赋值

    

解构同时也可用于对象,这不像数组,按次序排序而进行赋值,只要变量于属性同名即可对应上:

let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

第二个例子在其解构的对象中并没有baz的属性,所以便无法给 baz赋值,结果为undefined。

如果变量名与属性名对不上,却仍需要对其赋值,可以将变量名使用对象名将其囊括:

let { foo: baz } = { foo: "aaa", bar: "bbb" };

这样baz便可得其值为aaa,这也实际上说明了对象的解构赋值实是下面的简写:

let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

对象解构赋值,先是找到同名的属性,再赋值给变量,真正被赋值的是模式(foo)后的变量(baz),而不是模式。

let { foo: baz } = { foo: "aaa", bar: "bbb" };

对于嵌套结构对象也可以解构赋值,只要结构对的上即可:

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

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

这里p 只是模式,如果还需要整个p的变量解构的话,可以增加多一个变量名p。

let{ p, p:[x,{y}]} = obj;
对象解构赋值详解:

1、变量名如果和解构对象属性名不一致,可以给变量名加上与对象名相同的模式名称,然后访问该模式名称下对应的变量名即可。

2、这里的loc: a,意思为定义变量a,其模式名为loc,模式loc与node对象下的第一个loc进行匹配,输出的便是start对象,而loc:{start}等同于loc:{start: start},解构赋值给start的是loc对象下start对象的属性。

3、loc:{start:a}等同于loc:{start}/loc:{start: start},只是变量名由a变为了start。

const node = {
    loc: {
        start: {
            line: 1,
            column: 5
        }
    }
};
let {loc, loc:d,  loc:{start: a}, loc:{start}, loc:{start:{line: x, column: y}}} = node;
console.log(d);
console.log(a);
console.log(start);


函数参数的解构赋值

妈了个卖批,真的是啥都可以解构,俺解还不成吗。

[[1, 2], [3, 4]].map(([a, b]) => a + b);

map遍历数组,第一个元素[1, 2],进入函数function([a, b]),这个函数参数表面是一个数组,在数组传入的一刻就被解构为变量a和b,进行计算后返回存入数组。


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]

这里的方法参数是一个对象,传入一个对象后对对象属性进行解析并且赋值给x和y。

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

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
这里是为参数设置默认值,而不是为解构后赋值设默认值,单传入对象{x:3}的话,参数识别到了对象,但不为空,所以不启动默认值,而是用对象本身的值,也就是undefined,返回的最终结果也就是[3, undefined],要理解什么是对象,怎么样才是对象的解构。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值