ES6-解构赋值

一、解构赋值是什么

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

二 为什么使用解构赋值

根本上是为了获取对象或者数组内的数据更加方便。

三、解构赋值的分类

1.数组的解构赋值

eg:
let [a,b,c] = [1,2,3];
这种写法本质上属于模式匹配,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
不完全解构:等号左边的模式只匹配一部分的等号右边的数组。如果等号的右边不是数组,或者严格来说不是可遍历的结构,那么将会报错。

let [foo] = 1;
在这里插入图片描述

只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值。

默认值:

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

let [foo = true] = []; foo //true

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

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

ES6使用严格相等判断数组的某个位置是否有值,所以,一个数组成员必须严格等于undefined,默认值才会生效。

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

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

默认值还可以引用解构赋值的其他变量,但该变量必须已经声明。

let [x = 1,y = x] = []; //x=1;y=1

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

可以跳过元素获取:

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

可以获取剩余元素:

let [a,b, …c] = [1,2,3,4,5]; //a=1,b=2,c=[3,4,5]

2.对象的解构赋值

对象的结构赋值与数组的结构赋值最大的不同是,数组的元素是按次序排列的,变量的取值是由它的位置决定的;而对象的属性没有次序,变量必须与属性同名才能取到正确的值。

(1)变量名与属性名不一致的写法:

let {foo:baz} = {foo:'hello', bar:'world'} //baz = 'hello'

说明对象的解构赋值是下面形式的简写:

let {foo:foo} = {foo:'hello', bar:'world'} //foo = 'hello'

所以对象结构赋值的内部机制是:先找到对象内同名属性,然后再赋值给对应的变量 。真正被赋值的是后者baz,foo是匹配模式。

(2)对嵌套结构的对象进行解构:

let obj = {

p: [‘aaa’ , {y: ’ bbb’ }]

}`

let { p : [x , {y}]} = obj ; //此处p为匹配模式,不会被赋值,x、y为变量。x=‘aaa’,y=‘bbb’

若想p也被赋值:

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

(3)对象的解构也可以指定默认值,生效条件是 ,属性值必须严格等于undefined。

(4)将一个已经声明的变量用于解构赋值:

错误写法:下面的代码会报错,因为JS引擎会将 {x} 理解为代码块,从而发生语法错误。想解决这个问题,只有不将大括号写在行首。

let x;

{x} = {x:1};

正确写法:

let x;

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

(5)对象的解构赋值可以方便的将对象的方法赋值到某个变量。

let {log, sin, cos} = Math;

这样使用起来会方便很多。

(6)数组是特殊的对象,可以对其进行属性解构

let arr = [1,2,3];

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

arr的0键对应值为1,键对应值是3.

3.字符串的解构赋值

字符串能够解构赋值是因为被转换成了一个类似数组的对象。

const [a,b, c] = 'hello';

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

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

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

解构时,首先会将数值和布尔值转换为对象。 可以对数值和布尔值的包装对象进行赋值。

let {toString :s} = 123

s === Number.prototype.toString;// true
注意:解构赋值的规则是,只要等号右边不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值时会报错。

5.函数参数的解构赋值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指定默认值.

上述参数解析失败,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]

上面的代码是为move函数的参数指定默认值,而不是为x 、y指定默认值,所以结果会不一样。

四、解构赋值的应用

(1)交换变量的值

lwt x =1, y = 2

[x , y] = [y , x];

(2)从函数返回多个值

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

(3)函数参数的定义

解构赋值可以方便地将一组参数和变量对应起来。

参数是一组无序的值:

function f([x, y ,z]){......}

f([1, 2, 3]);

参数是一组无次序的值

function f({x,y,z}){......};

f({z:344, y:2, x:1});

(4)提取JSON数据

let jsonData = {

id:42,

status:‘ok’

}

let {id , status} = jsonData;

(5)函数参数的默认值

function = (url, { async = true, status: ‘ok’}) { …}

指定参数的默认值,这样就避免了在函数内部再写 var async = config.async || true;

(6) 遍历Map解构

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

var map =new Map();

map.set( ‘first’, ‘hello’);

map.set( ‘second’ , ‘world’);

for([key,value] of map){

console.log(key + 'is ’ +value);

}

在这里插入图片描述
注意,获取value时的写法,不加逗号得到的还是key

for( [ , value] of map){

console.log(value);

}

(7)输入模块的指定方法

加载模块时,往往需要指定输入的方法。解构赋值使得输入语句非常清晰。

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

### ES6 对象解构赋值 #### 基本语法 对象的解构赋值允许提取对象中的属性并将其分配给变量。基本形式如下: ```javascript let obj = { prop1: "value1", prop2: 42 }; let { prop1, prop2 } = obj; console.log(prop1); // 输出:"value1" console.log(prop2); // 输出:42 ``` 此操作会创建两个新变量 `prop1` 和 `prop2`, 它们的初始值分别对应于对象 `obj` 中相应键对应的值[^1]。 #### 设置默认值 当尝试从不存在或未定义的对象属性获取值时,可以通过指定默认值来处理这种情况: ```javascript let userSettings = { theme: 'dark', }; // 使用默认参数 let { theme = 'light', fontSize = 16 } = userSettings; console.log(theme); // dark (来自实际数据) console.log(fontSize); // 16 (使用了默认设置) ``` 这里展示了如何为可能缺失的配置项提供合理的回退选项[^2]. #### 属性重命名 有时希望使用的局部变量名称不同于原始对象内的键名,在这种情况下可以采用别名机制完成映射关系建立: ```javascript const person = { firstName: 'John', lastName: 'Doe' }; let { firstName: name, lastName: surname } = person; console.log(name); // John console.log(surname); // Doe ``` 上述代码片段说明了即使原对象字段名为 `firstName` 和 `lastName`, 可以通过冒号后的部分自定义新的绑定目标名字[^3]. #### 处理剩余属性 对于那些不参与直接匹配却仍然存在于源对象里的其他成员,则可通过扩展运算符(`...`)捕获它们形成一个新的独立实体: ```javascript var sourceObj = { id: 7, title: "A Tale of Two Cities", author: "Charles Dickens", yearPublished: 1859 }; let {id, ...bookInfo} = sourceObj; console.log(id); // 7 console.log(bookInfo.title);// A Tale of Two Cities console.log(bookInfo.author); // Charles Dickens console.log(bookInfo.yearPublished); // 1859 ``` 这段例子表明除了显式声明过的 `id` 字段外,其余所有条目都被收集到了 `bookInfo` 这个新对象里去了.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值