变量的解构赋值

变量的解构赋值

变量的解构赋值我把它理解为快速的从的、已知数据中提取你想要拿到的数据,既从等号右边复制给左边想要被复制的变量。

数组的解构赋值

下面列举下几中常见的数组解构赋值

var [a,b,c]=[1,2,3,4]
console.log(a,b,c)
// 1 2 3
var [a,b,c]=[1,2]
console.log(a,b,c)
// 1 2 undefined
var [a,[b,c],d]=[1,2,3]
// 报错
var [a, ,c]=[1,2,3]
// a 1
// c 3

可以很直观的看出,等号左边被复制的变量应该按照一一对应的顺序与等号后面对应,比入数组和字符串就是成立的,对应位置的变量也应该相同,第三个例子中就是应为[b,c]与2无法对应,无法进行解析赋值。

let [foo] = 1;    //number
let [foo] = false;    //boolean
let [foo] = NaN;    //NaN
let [foo] = undefined;    //undefined
let [foo] = null;    //null
let [foo] = {};    //object

默认值

默认值的设置,可以在解析赋值中为赋到值的变量设置一个默认值,当赋值成功过后默认值就被覆盖。

var [a,b,c=3,d=4]=[1,2, ,10]
console.log(a,b,c,d)
// 1 2 3 10

注意,当右边被复制为null的时候,默认值还是会被覆盖,只有为undefined的时候才会启用默认值,如下

var [a,b=2,c=3,d=4]=[1, ,null,undefined]
console.log(a,b,c,d)

同时默认值必须是已知的,即可以采用变量,但是必须是实现申明的变量。

对象的解构赋值

对象的解构赋值大致可以通过两个例子来解释下,通过对象的解构赋值赋值的本质上的机制是啥

let {a,b}={b:1,a:2}
// a 2 b 1
let {a:b,a}={a:1}
// a 1  b 1

通过上面两个例子其实我们可以看出大概的赋值规则

  • 首先对象的解构赋值是根据寻找相同key值来赋值的,而数组则是根据顺序来赋值
  • 其实对象的解构赋值并不是赋值key值,而是赋值key值指向后面的变量,即上面的例子可以改写为
let {a:a,b:b}={b:1,a:2}
// a 2 b 1

let {a:b,a:a}={a:1}
// a 1  b 1

这样子的话就可以明显的看出其实是复制给key值指向的变量,默认与key值相同,这样看就非常明了了

已声明变量赋值

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

({a}={a:1})
// a 1

var a
var {a}={a:1}
// a 1

var a
let {a}={a:1}
// 报错

导致上面第一个例子报错的原因其实是因为,由于{a}被认为是一个代码块,代码块跟对象赋值肯定不成立,后面由于存在let重复声明了。

解构赋值为浅复制

var a={
    b:{
        c:1
    }
}
var {b}=a
b.c //1
b.c=2
a.b.c //2

可以看出解构赋值他是一个浅复制的过程。

我们发现在对一个对象进行解构赋值的时候,等号右边可以为数组,数组的下标可以作为key值,相反对数组进行解构赋值时,右边必须为数组。

var array=[1,2,3,4]
var {
    0:a,
    2:b
}=array
// a 1 b 3

var [a,b]={a:1,b:2}
// 报错

默认值

其实对象的默认值跟数组的定义差不多,都是设置为未赋值成功情况下的值

var {
    a,
    b:c=1,
    d=10
}={a:2}
console.log(a,c,d)
// 2 1 10

字符串的解构赋值

var [a,b]='你好'
// a 你 b 好

var a='asdasd'
var {split:method}=a
method.apply('abc',[''])
// [a,b,c]

通过上面的例子,有时候我们可以看成是数组的解构赋值,这样子的话就很好理解,同时也可以通过解构赋值将内置的方法继承出去。

函数参数的解构赋值

基本用法

function c(x,y=2){
    console.log(x,y)
}
c(1)

与解构赋值结合的用法

function demo({x,y=5}){
    console.log(x,y)
}
demo({}) // undefined 5
demo({x:1,y:2}) // 1 2
demo({x:1}) // 1 5
demo() // 报错

这个相当于对象的解构赋值的操作,所以当传入的参数为空的时候,无法扩展赋值,x未定义,所以报错,其他的按照正常的对象解构赋值就可以得出结果。

当给函数的参数设置默认值的情况

function demo1({x,y}={x:0,y:1}){
    console.log(x,y)
}

function demo2({x:0,y:1}={}){
    console.log(x,y)
}
demo1() 0 1
demo2() 0 1

demo1({}) undefined undefined
demo2({}) 0 1

demo1({x:3}) 3 1
demo2({x:3}) 3 undefined

通过上面的例子我们就能够很好理解了,在未给函数传参的情况下,函数参数的默认参数才会起作用,即等号右边才会起作用。

函数的length

函数的length属性其实就是除去存在默认值的参数的个数。

(function (x=1,y){}).length  //1

因为length属性的含义是,该函数预期传入的参数个数

(function (...args){}).length // 0

注意:在设置了默认值之后的未传默认值的参数也不算入length

(function(x,y=2,z,y){}).length
// 1

参数变量其实默认声明了,所以在函数内不能再申明了,否则会报错

参数的位置

一般把带有默认值的参数都放在后面,如果不为末尾,这样的话不传递该参数的话,后面是无法传递的,同时会导致length属性.

function demo(x=1,y){
    console.log(x,y)
}
demo(,1) //报错
demo(null,1) //null 1

记住,只有当赋值为undefined的时候才会采用默认值

作用域

函数参数中的变量设置默认值时,会生成一个单独的作用域。

var a=2
function demo(a,b=a){
    console.log(b)
}
demo(1)
// 1

var a=2
function demo(a,b=function(){a=1}){
    var a=3
    b()
    console.log(a)
}
demo()
// 3

var a=2
function demo(a,b=function(){a=1}){
    a=3
    console.log(a)
}
demo()
// 1
  • 上面的第一个例子可以很清楚的看出,函数申明中参数b的默认参数a并不是在外面定义的全局变量。
  • 例二可以看出函数中重新申明的a与参数变量的a也不是在同一作用域,所以输出结果为3
  • 例三可以看出不声明a,那么这个a的指向就是参数变量a,所以结果为1

圆括号问题

在解构赋值当中,一般我们不建议存在圆括号,应为会产生各种错误,除非那种结构会产生歧义的情况下才需要使用圆括号,下面来看下那些错误的方式和需要用的地方

  • 变量声明中不能加圆括号
  • 函数参数中,不能带有圆括号。
  • 赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中

可以使用括号例子

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

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

总结:尽量不要使用圆括号加入到解构赋值中去

用处

1.交换值

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

2.从函数返回多个值

函数只能返回一个值,可以利用解构同时生成多个值

function demo(){
    return [1,2,3]
}
var [a,b,c]=demo()

function demo1(){
    return {x:1,y:2}
}
var {x,y}=demo1()

3.函数参数的定义

传递有序参数
function demo([x,y]){
    console.log(x,y) // 1 2
}
demo([1,2])

传递无序参数
function demo1({x,y}){
    console.log(x,y) //2 1
}
demo1({y:1,x:2})

4.JSON数据的提取

// 提取json中有用的数据
var res={
    a:12323,
    b:function(){}
}
var {a,b}=res

5.设置参数的默认值

设置默认值,防止报错等

**6.遍历Map解构

var map=new Map()
map.set('你好','世界')
map.set('hello','world')
for(let [key, value] of Map){
    console.log(key+' '+value)
}
// 你好 世界 
// hello world

6.输入模块的指定方法

import {a, b} = require(model)

加载模块时,提取所需的部分方法,很便捷明了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值