[ES6]新特性,都什么时候了,ES6的解构你还不学?

前言

ES6(ECMAScript 2015)引入了许多新的语法特性,其中之一就是变量的解构赋值。这个特性使得在声明和赋值变量时更加灵活和方便。

我们在之前的文章当中,已经浅学过如何对数组和对象进行解构。今天,我来进行拓展和补充!

之前的文章可以参考:潜聊ES6新特性--解构【干货】 - 掘金 (juejin.cn)

正文

ES6(ECMAScript 2015)引入了许多新的语法特性,其中之一就是变量的结构赋值。这个特性使得在声明和赋值变量时更加灵活和方便。

一、数组的解构赋值

数组的解构赋值是 ES6 中引入的一项强大功能,它使得从数组中提取值并赋给变量变得更加简洁和灵活。

接下来,我们通过案例来进行学习!

以前我们的赋值方式:

js 复制代码
let a = 1
let b = 2
let c = 3

但是在ES6当中,允许我们这样赋值!

js 复制代码
let [a,b,c]=[1,2,3]
console.log(a);//输出:1
console.log(b);//输出:2
console.log(c);//输出:3

这一点其实,我们在潜聊的时候,我们就聊过了,并且这种方式,a,b,c的取值也是会取到数组的中的对应位置的值!

这里,我们就要聊到模式匹配了!

数组模式匹配是一种通过模式匹配语法从数组中提取值的方法。通过方括号内的变量名,我们可以将数组中对应位置的值赋给相应的变量。

也就是说,我们可以忽略某些元素.

1. 忽略某些元素

js 复制代码
let [a,,c]=[1,2,3,4]
console.log(a);//输出:1
console.log(c);//输出:3

我可以这样来进行模式匹配!甚至是...的解构方法!这种方式是是剩余元素的获取.

2. 剩余元素

js 复制代码
let [a,...c]=[1,2,3,4]
console.log(a);//输出:1
console.log(c);//输出:[ 2, 3, 4 ]

这其实就是一种解构方法!假如解构不成功呢?那么输出的毫无疑问就是undefined

我们来看看案例:

js 复制代码
let [,,,,a]=[1,2,3,4]
console.log(a);//输出:undefined

当然,还有不完全解构这个概念,解构的过程并没有把数组中的所有数据都解构出来!这也是可以成功的!

3. 不完全解构

js 复制代码
let [a,b,c]=[1,2,3,4]
console.log(a);//输出:1
console.log(b);//输出:2
console.log(c);//输出:3

注意,当我们使用let [变量] = []这种方式进行解构的时候,如果等号右边不是数组[],那么我们的编译器将会报错!严格来说是不可遍历的结构!

还有一种嵌套的解构方式!

4.嵌套数组模式匹配

js 复制代码
let [a, [b, c], d] = [1, [2, 3], 4];
console.log(a); //输出:1
console.log(b); //输出:2
console.log(c); //输出:3
console.log(d); //输出:4

实际上,只要是具有Iterator接口的数据结构类型都可以采用数组结构的方式进行解构!比如Set结构!

js 复制代码
let set = new Set([1,2,3]);
let [a,b,c]=set
console.log(a);//输出:1
console.log(b);//输出:2
console.log(c);//输出:3

5. 默认值

数组模式匹配也支持设置默认值,当解构的值为 undefined 时,变量会取默认值。

js 复制代码
javascriptCopy codelet [a, b, c = 3] = [1, 2];
console.log(c); // 3

在这个例子中,由于数组中并没有第三个元素,所以变量 c 取到了默认值 3。

但是在默认值当中,有两种情况,我们要看看结果!

js 复制代码
let [a=1]=[undefined]
let [b=2]=[null]
console.log(a);//输出:1
console.log(b);//输出:null

如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。所以null会替代掉我们设置的默认值!

当然还有函数比较特殊!

js 复制代码
function foo(){}
let [a = foo()]=[1]
console.log(a);//输出:1

其实,这就等价于:

js 复制代码
let a;
if ([1][0] === undefined) {
  a = foo();
} else {
  a = [1][0];
}

默认值也赋值为其他解构变量,前提是这个变量已经声明!

js 复制代码
let [a=1,b=a] = []
console.log(a);//输出:1
console.log(b);//输出:1

二、对象的解构

在之前的文章,我们也介绍了对象的解构方式,今日我再学习一遍!

与数组类似,我们可以差不多这种方式对对象进行解构!但是又有点不同!

我们来看看:

js 复制代码
let obj = {name:'小明',age:19}
let {name:name,age:age}=obj
// 也可以写成这样
let {name,age} = obj
console.log(name);//输出:小明
console.log(age);//输出:19

对象可以不按次序进行解构,而数组是按次序解构,数组中变量的取值是按次序而定,而对象中,变量必须要于属性同名,才能取到你想要的值。

如果解构得不到值,会输出undefined,如下:

js 复制代码
let obj = {name:'小明',age:19}
let {address}=obj
console.log(address);//输出:undefined

因为我们的对象obj中没有address这个属性,所以变量address取不到值。

1、修改变量名

我们再解构的时候,也可以修改变量名,但是必须写成以下这种格式!

js 复制代码
let obj = {name:'小明',age:19}
let {name:名字,age:年龄}=obj
console.log(名字);//输出:小明
console.log(年龄);//输出:19

其中nameage是匹配模式,用于匹配对象中的key值,名字年龄是我们设定的变量名!

2、嵌套结构的对象

和数组一样,对象可以对具有嵌套结构的对象进行解构!我们来给大家看看一个案例!

js 复制代码
let obj = 
{name:'小明',
age:19,
like:{
    like1:'coding',
    unlike:{
        unlike1:'play games'
    }
}
}
let {
    name,
    age,
    like:{
        like1,
        unlike:{
            unlike1
        }
    }
} = obj;
console.log(name);//输出:小明
console.log(age);//输出:19
console.log(like1);//输出:coding
console.log(unlike1);//输出:play games

注意!likeunlike是匹配模式,不是变量,不会对其进行赋值!假如我们要对like这种key进行赋值该如何操作呢?我们来上一个简单的案例!

js 复制代码
let obj = {like:{like1:'coding'}}
let {like,like:{like1}} = obj
console.log(like);//输出:{ like1: 'coding' }
console.log(like1);//输出:coding

这样,我们就也能对like赋值成为一个变量了!如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。

js 复制代码
let obj = {like:{like1:'coding'}}
let {unlike:{like1}}//报错

3、默认值

和数组一样,对象解构也能具备默认值!我们直接来看案例吧!

js 复制代码
let obj = {name:'小明'}
let {name='小红',age = 19}=obj
console.log(name);//输出:小明
console.log(age);//输出:19

如果我们声明的变量有默认值,并且在对象中能解构出一个对应的key值,那么这个默认值将会被覆盖!如果没有这样一个key值与我们声明的变量进行匹配,那么这个变量将会被设为默认值!

4、获取对象的方法

我们可以通过设置一个变量,来获取对象当中的方法,当然变量名要与方法名进行匹配!

js 复制代码
let {max} = Math
console.log(max(1,100));//输出:100

例如,我们这个案例当中,我们用max这样的变量获取Math对象当中的max方法!这样我们就可以直接拿着max方法进行使用啦!

5、获取对象继承的属性

我们也可以通过对象解构,获取到对象继承的方法!例如:

js 复制代码
let obj = {}
let obj2 ={fn:function(){}}
Object.setPrototypeOf(obj, obj2);//将obj的原型设为obj2
let {fn} = obj
console.log(fn);//输出:[Function: fn]

我们在这个案例里面,将obj的原型设置为obj2,在用一个变量fn获取到了obj原型中的属性!

当然在对象解构的时候!有三个注意的点!

一、用以声明的对象要注意写法!

js 复制代码
// 错误的写法
let x;
{x} = {x: 1};//会报错:SyntaxError: syntax error

//正确的写法
let x;
({x} = {x:1});

这是为什么呢?这是因为当我们使用已经声明的变量!我们要注意写法!为什么呢?因为我们的JavaScript编译器会把{x}理解成一个单独的代码块!所以我们要加一个()避免JavaScript编译器将其识别为代码块!

二、解构赋值语句,右边部分可以不防止任何东西!这样就会出现一些奇奇怪怪的代码!

例如:

js 复制代码
let obj = {name:'小明'}
let {} = obj

虽然这种代码没有任何意义,但是的的确确是合法的,也可以正常运行!

三、数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

我们来看看案例!

js 复制代码
let arr = [1,2,3]
let {0:first,1:next,2:last} = arr
console.log(first);//输出:1
console.log(next);//输出:2
console.log(last);//输出:3

对于数组,我们使用对象的解构方法,对应的key值其实就是数组的下标!

三、字符串的解构赋值

其实,字符串的解构就有点类似数组了!

js 复制代码
let str = 'coding'
let [a,b,c,d,e,f]= str
console.log(a);//输出:c
console.log(b);//输出:o
console.log(c);//输出:d
console.log(d);//输出:i
console.log(e);//输出:n
console.log(f);//输出:g

同时,类似数组的对象都有一个length属性,我们可以对这个属性进行解构!

js 复制代码
let str = 'coding'
let {length:len}= str
console.log(len);//输出:6

注意!我们这里要使用对象的花括号{},而不是数组的方括号[]

四、数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值或者布尔值,则会先转为对象。

javascript 复制代码
let {toString: num} = 666;
console.log( num === Number.prototype.toString) //输出:true
let {toString: bol} = true;
console.log( bol === Boolean.prototype.toString) //输出:true

上述案例当中,数值和布尔值的包装对象都有toString属性,因此变量numbol都能取到值。

当我们使用解构赋值时,如果等号右边的值不是对象或数组,JavaScript 会尝试将其转为对象。然而,由于 undefinednull 无法被转为对象,因此在对它们进行解构赋值时,会导致错误。简而言之,试图对 undefinednull 进行解构赋值会引发错误。

上案例:

javascript 复制代码
let { prop: un } = undefined; // 会抛出TypeError
let { prop: nu } = null; // 会抛出TypeError

五、函数参数的解构赋值

函数的参数也是可以解构赋值的!

javascript 复制代码
function num([a,b]){
    console.log(a);//输出:1
    console.log(b);//输出:2
}
num([1,2])

在我们上面的例子当中,我们的函数num表面上接收了一个数组,其实对于函数体内部来说,接收的是一个解构后的数组,也就是接收了两个变量a,b

同样的,函数的解构也可以使用默认值!

js 复制代码
function num([a = 2,b = 3]){
    console.log(a);//输出:1
    console.log(b);//输出:3
}
num([1])

在上述案例当中,我们为函数的形参b提供了一个默认值 3 ,因为我们没有给形参b传一个实参,所以在解构的时候,变量b就采用了默认值!而形参a,我们为它传了一个实参,所以默认值就会被我们传的值所覆盖!

其实函数解构还有更多写法!大家可以自主去学习一下!

六、总结:用途

  1. 数组解构:

    • 从数组中提取值,赋值给变量,使代码更简洁易读。
    • 允许跳过不需要的元素,通过逗号占位符。
    • 支持默认值,用于处理数组中可能不存在的元素。
  2. 对象解构:

    • 从对象中提取属性值,以便更方便地使用这些值。
    • 可以使用别名,使得变量名更具有描述性。
    • 也支持默认值,处理可能不存在的属性。
  3. 函数参数解构:

    • 允许函数参数直接从传入的对象或数组中提取值,提高函数参数的可读性。
    • 可以使用默认值,处理缺失的参数。
  4. 嵌套解构:

    • 处理嵌套的数据结构,如对象中嵌套对象或数组,使得提取数据更便利。
  5. 剩余/扩展操作符:

    • 使用剩余操作符可以获取数组中的其余元素,使得处理动态长度的数组更方便。
    • 扩展操作符可以用于合并数组或对象。
  6. 交换变量值:

    • 使用解构可以更简洁地交换两个变量的值,而无需借助中间变量。
javascript 复制代码
let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 输出: 2 1
  1. 提取函数返回的对象属性:
    • 从函数返回的对象中直接提取属性,避免了临时变量的使用。
javascript 复制代码
function getUser() {
  return { id: 1, name: 'John' };
}

const { id, name } = getUser();
console.log(id, name); // 输出: 1 John
  1. 多值返回:
    • 函数可以返回多个值,然后通过解构一次性获取这些值。
javascript 复制代码
function getValues() {
  return [1, 2, 3];
}

const [x, y, z] = getValues();
console.log(x, y, z); // 输出: 1 2 3

好了,我们今天的学习就到这里了!欢迎大家评论留言哦!

点个赞鼓励支持一下吧!🌹🌹🌹 引用参考:ES6 入门教程 - ECMAScript 6入门 (ruanyifeng.com)

个人gitee库:MycodeSpace: 主要应用的仓库,记录学习coding中的点点滴滴 (gitee.com)

相关推荐
阿伟来咯~3 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端8 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱11 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai20 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨21 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
bysking1 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js