《es6标准入门》学习笔记-第三章 变量的解构赋值

基本用法

按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
es6允许以下面的方法赋值

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

这种写法属于“匹配模式”,只要等号左右两边的模式相同,左边的变量就会被赋予对应的值
解构赋值可以使用var let const

解构的例子
let [foo,[[bar],baz]]=[1,[[2],3]];
let [,,third]=[1,2,3]
let [head,...tail]=[1,2,3,4]//head=1 tail=[2,3,4]
let [x,y,z]=["a"]//x="a",y=undefined z=[]
解构不成功

如果解构不成功,则变量的值等于undefined

var [foo]=[]
var [bar,foo]=[1]
不完全解构

左边的模式只匹配右边的一部分

var [x,y]=[1,2,3];
let [a,[b],c]=[1,[2,3],4]
解构报错

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

let [a]=1;//TypeError
let [b]=false;//TypeError
let [c]=NaN;//TypeError
let [d]=null;//TypeError
let [e]=undefined;//TypeError
let [f]={}//TypeError

此处内容将在13-15章详细说明,此处仅为扩展阅读
数组解构赋值要求右边的值具有Iterator接口或者转为对象后具有Iterator接口
对于set结构,也可以使用数组解构

var [a,b,c]=new Set(["a","b","c"])

只要具有Iterator接口就可以数组解构赋值

function* fibs(){
    var a=0;
    var b=1;
    while(true){
        yield a;
        [a,b]=[a,a+b];
    }
}
var [one,tow,three,four,five,six]=fibs();
console.log(six);//6
默认值

解构赋值允许指定默认值

var [foo=1]=[];
var [x,y=1]=["a",undefined]

如果一个右侧数组成员不严格等于undfined,则默认值不生效

var [foo=1]=[null];//null

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

function f(){
    cosnole.log("its a function")
}
var [a=f()]=[1]//1

因为a能取到值,所以不进行计算

默认值可以使用其他解构赋值的变量,但该变量必须为已声明过的

let [x=1,y=x]=[]//[1,1]
let [x=y,y=1]=[]//y is not defined

对象的解构赋值

解构不仅可以用于数组,还可以用于对象
对象的解构,变量和属性必须同名,才能接收到值

var {a}={a:1,b:2}//1
var {c}={d:3,f:4}//undefined

如果属性名不一致的,则需要将变量写成具有相同属性名的属性的值的形式

var {foo:bar}={foo:1}
//bar===1,foo===undefined

在上面的代码中,foo是没有被赋值的,而bar被赋值了。
对象解构的内部机制是,先找到同名属性,再赋值给变量,真正被赋值的是后者而不是前者。

var {foo}={foo:1}
//实际为{foo:foo}={foo:1} 被赋值的是foo:foo中的后者

对象解构中被赋值的是属性对应的变量而不是模式

和数组一样,解构也可以用于嵌套的对象

var obj={
    p:[
        "hello",{y:"word"}
    ]
}
let {p:[x,{y}]}=obj//p是模式,不会被赋值

嵌套赋值例子

let obj={};
let arr=[];
({foo:obj.prop,bar:arr[0]})={foo:123,bar:true}
console.log(obj)//{prop:123}
console.log(arr)//[ture]

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错

var {foo:{bar}}={baz:'baz'}
//TypeError: Cannot match against 'undefined' or 'null'

已声明的变量用于解构赋值这一块的内容,我在测试时没有发现问题,是可以正常执行的,不知是属于版本问题,还是作者有误,待考证后再补充

字符串的解构赋值

字符串会转为一个类似数组的对象进行解构赋值

const [a,b,c]="hello";//['h','e','l']
const {lengh:len}="hello";//len===5

数值和布尔值的解构赋值

如果右边卫数值或者布尔值,则会先转为对象

let {toString:s}=123;
console.log(s===Number.prototype.toString)//true

let {toString:y}=fale;
console.log(y===Boolean.prototype.toString )//true

上面的代码中,数值和布尔值的包装对象都有toString属性,所以变量能取到值
由于null和undefined无法转为对象,所以对他们解构会报错

let {prop:x}=undefined;
//TypeError: Cannot match against 'undefined' or 'null'

let {prop:x}=null;
//TypeError: Cannot match against 'undefined' or 'null'

函数参数的解构赋值

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

function add([x,y]){
    return x+y
}
var arr=[1,2];
add(arr)//3

函数参数的解构也可以使用默认值

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

注意:下面的写法会得到不一样的结果

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

上面的代码是为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到不一样的结果
undefined会出发函数参数的默认值

圆括号问题

虽然在书中提出了圆括号的处理问题,但是一般的es6编码规范提出解构语句中统一不使用圆括号,所以不在此处重点说明,如果有需求的请查看原书

用途

交换变量的值
[x,y]=[y,x]
从函数返回多个值
function example(){
    return [1,2,3]
}
var [a,b,c]=example();

function example(){
    return {a:1,b:2,c:3}
}
var {a,b,c}=example();
函数参数的定义

方便的将一组参数和变量名对应起来

function example([x,y,z]){
    return x+y+z
}
example([1,2,3]);

function example({x,y,z}){
    return x+y+z
}
example({z:1,x:2,y:3});
提取json
var jsonData={
    id:42,
    status:"ok",
    data:[867,5309]
}

let{id,status,data:number}=jsonData;
函数参数的默认值
$.ajax=function(url,{
    astnc=true,
    cache=true
}){
}

避免了函数体内写 var foo=config.foo||’default foo’

遍历map解构

在后面讲解map时会做补充,这边仅做扩展阅读

var map= new Map();
map.set('first','second');
if(let [key,value] of map){
    console.log(key,value)
}

获取键名

for(let [key] of map){ ... }

获取值

for(let [,value] of map){ ... }
输入模块的指定方法
const {sourceMapConsumer,SourceNode}=require("resource-map")

import {sourceMapConsumer,SourceNode} from "resource-map"  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值