【ES6入门标准】JavaScript中的变量的解构赋值的详细使用和应用场景

在这里插入图片描述

😁 作者简介:一名大三的学生,致力学习前端开发技术
⭐️个人主页:夜宵饽饽的主页
❔ 系列专栏:前端js专栏
👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气

​🔥​前言:

这是自己在学习JavaScript的学习笔记和总结,希望可以帮助到你,解构赋值是一个非常棒的方法,可以使代码易读,简洁,高效

第3章 变量的解构赋值

3.1 数组的解构赋值

3.1.1 基本用法

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

1.解构成功

let [foo, [[bar], baz]]=[1, [[2], 3]]
//foo=1,bar=2,baz=3


let [head,...tail]=[1,2,3,4]
//head=1,tail=[2,3,4]

2.解构失败

如果解构失败,变量的值就等于undefined

let [foo]=[];
let [bar,foo]=[1];

//foo=undefined

以上两种情况的foo的值都为undefined

3.解构不完全

等号左边的模式只匹配一部分的等号右边的数组,这种情况下,解构依然是可以成功的

let [x,y]=[1,2,3]

4.解构异常

如果等号的右边不是数组(严格的说不是可遍历的结构),那么解构将会报错

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

上面的语句都会报错

3.1.2 默认值

解构赋值允许指定默认值

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

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

⭐️ 注意:要使默认值生效,数组成员的值必须严格等于undefined

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

以下这种情况默认值不会生效

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

如果一个默认值是一个表达式,那么这个表达式是惰性求值,即只有在用到时才会求值

function f(){
    console.log('aaa')
}

let [ x=f() ]=[ 1 ] 

上面的代码中,因为x能取到值,所以函数f根本不会执行。

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

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

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

最后的表达式之所以会报错,是因为x使用到y时,y还没有声明

3.2 对象的解构赋值

对象的解构赋值与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值是由它的位置决定的,而对象的属性没有次序,所以我们要从变量与属性名考虑

3.2.1.变量与属性名同名
let {bar foo}={foo:'aaa',bar:'bbb'}
//foo='aaa'
//bar='bbb'
3…2.2.变量与属性名不一致
var {foo:baz}={foo:'aaa',bar:'bbb'}
//baz='aaa'

这两种方法,我们如果从对象的简介形式考虑,会发现这两种情况是一样的

let {bar:bar,foo:foo}={foo:'aaa',bar:'bbb'}

也就是说,对象的解构赋值的内部机制是找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者,

上面的代码中,foo是匹配的模式,baz才是变量,真正被赋值的是变量baz,而不是模式foo

3.2.3.解构嵌套结构的对象
let obj={
    p:[
        'Hello',
        {y:'World'}
    ]
};

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

//x='Hello'
//y='World'

❗️ 注意:这时候p是模式,不是变量,因此不会被赋值,如果我们想要p也作为变量去赋值的话,可以这样写

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

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

//x='Hello'
//y='World'
//p=['Hello,{y:'World'}']

或者我们也可以使用其他已经声明的变量来嵌套赋值

let obj={}
let arr=[];

({foo:obj.prop,bar:arr[0]}={foo:123,bar:true})
//obj={prop:123}
//arr=[true]

我们可以注意到,解构语句打上了圆括号,这是因为,我们不打上圆括号的话,JavaScript引擎会将{x}理解成为代码块,从而发生语法错误,只有不将大括号写在行首,避免JavaScript将其解释为代码块,关于解构赋值与圆括号的关系请看下文

3.2.4 对象解构的默认值

默认值生效的条件依旧是undefined

var {x=3}={}
//x=3

var {x:y=3}={}
//y=3

var {x:y=3}={x:5}
//y=5
3.2.5 现有对象的解构
let {log,sin cos}=Math

上面的代码会将Math对象的对数,正弦,余弦三个方法赋值到对应的变量上,使用起来就会方便很多

3.3 字符串的解构赋值

字符串在解构赋值时,会被转换为一个类似数组的对象

const [a,b,c,d,e]='hello'
//a='h'
//b='e'
//c='l'
//d='l'
//e='o'

类似数组的对象都有一个length属性,因此也可以对这个属性进行解构赋值

let [length:len]='hello'
//len=5

3.4 数值和布尔的解构赋值

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

let {toString:s}=123
//s===Number.prototype.toString

解构赋值的规则是,只要等号的右边不是数值或对象,就要转换为对象

3.5 函数参数的解构赋值

3.5.1 基本用法
function add([x,y]){
	return x+y
}

add([1,2])

上面的代码中,函数add的参数表面上是一个数组,但在传入参数的那一刻,数组被解构成变量x和y,对于函数内部的代码来说,它们能感受到参就是x和y

3.5.2 使用默认值
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]

上面的代码中,函数move的参数是一个对象,通过对这个对象进行解构,得到变量y和x的值,如果解构失败,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指定默认值,所以会有不同的结果

😄:理解的小技巧

你可以先不考虑参数中的({x,y}={x:0,y:0})的右边,就当做真正的参数解构赋值,({x,y})

然后去赋值

当遇到什么都没有传入,那么就考虑函数本身的默认值,就比如

function fn(x=3){}

fn()

这样的话,函数的默认值x=3就成立啦

3.6 圆括号的问题

❓ 问题:解构赋值虽然方便,但是解析起来并不容易,对于编译器来说,一个式子到底是模式还是表达式,没有办法从一开始就知道,必须解析到等号才能知道。

由此带来的问题是,如果模式中出现圆括号该怎么处理?ES5的规则是,只要有可能导致解构的歧义,就不得使用圆括号

但是,这条规则实际上不那么容易辨别,处理起来相当麻烦,因此建议,只要有可能,就不要在模式中使用圆括号

3.6.1 不能使用圆括号的情况

1. 变量声明语句

let [(a)]=[1]

let {x:(c)}={}
let ({x:c})={}
let {(x:c)}={}
let {(x):c}={}

let {o:({p:p})}={o:{p:2}}

上面6个语句会报错,因为它们都是变量声明语句,模式不能使用圆括号。

2.函数参数

函数参数也属于变量声明,因此不能使用圆括号

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

//报错
function f([z,(x)]){return x;}

3.赋值语句的模式

//全部报错
( { p:a } )={ p:42 }
( [a] )=[5]

上面的代码将整个模式放在圆括号之中,导致报错

//报错
[( { p:a } ),{x:c}]=[{},{}]

上面的代码将一部分模式放到圆括号之中,导致报错

3.6.2 可以使用圆括号的情况

这种情况只有一种就是:赋值语句的非模式部分可以使用圆括号

[(b)]=[3]   //正确
({p:(d)}={}) //正确
[(parseInt.prop)]=[3] //正确

上面的三个语句都是可以正确执行,因为它们都是赋值语句,而不是声明语句,另外它们的圆括号都不属于模式的一部分

  1. 第1行语句中,模式是取数组的第一个成员,跟圆括号无关
  2. 第2行语句中,模式是p而不是d
  3. 第3行语句与第1行语句的性质一样

3.7 用途

3.7.1 交换变量的值
let a=1
let b=2
[a.b]=[b,a]

上面的代码交换了变量的值,这种写法不仅简单,而且易读

3.7.2 从函数返回多个值

一般来说,函数只能返回一个值,要想返回多个值,必须将它们放在数组或者对象里返回,当使用解构赋值时,取出这些值就变得非常方便

//返回一个数组
function example(){
    return [1,2,3]
}

let [a,b,c]=example()
console.log("a=%s,b=%s,c=%s",a,b,c)
//a=1,b=2,c=3

//返回一个对象
function exampleobj(){
    return {
        foo:1,
        bar:2
    };
}

let {foo,bar}=exampleobj()
console.log("foo=%s,bar=%s",foo,bar)
//foo=1,bar=2
3.7.3 函数参数的定义

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

//参数是一组有序的值
function f([x.y.z]){...}
f([1,2,3])
//参数是一组无序的值
function fe({x,y,z}){...}
f({z:3,y:2,x:1})
3.7.4 提取JSON数据

解构赋值对提取JSON对象中的数据尤其有用

let jsonData={
	id:42,
    status:'ok',
    data:[867,5309]
}

let {id,status,data:number}=jsonData

console.log(id,status,number)
//42,ok,[867,5309]
3.7.5 函数参数的默认值
jQuery.ajax=function(url,{
    async=true,
    beforeSend=function(){},
    cache=true,
    complete=function(){}
	...
}){
    
}

指定参数的默认值,这样就避免了在函数体内部再写var foo=config.foo||‘default foo’ 这样的语句了

3.7.6 输入模块的指定加载方法
const {SourceMapConsumer,SourceNode}=require("source-map")

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值