赋值解构

目录:

  1. 数组的解构赋值
  2. 对象的解构赋值
  3. 字符串的解构赋值
  4. 数值和布尔值的解构赋值
  5. 函数参数的解构赋值
  6. 用途

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

数组的结构赋值

以前为变量的赋值只能直接指定值

let a = 1;
let b = 2;
let c = 3;

在ES6中允许写成这样的:let [a,b,c] = [1,2,3] ,这种方式表示可以从数组中提取值,并按照对应的位置对变量赋值。本质上这种写法属于“匹配模式”,只要等号两边的模式相同,左边的变量就会被赋予对应得值,下面是一个嵌套数组进行解构赋值得例子。

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

从上面得例子中我们可以看到数组得解构赋值其实是等号两边的数组的相对应位置上的值赋值:请看下面的例子

//例一:
let [foo,[[bar],baz]] = [1,[[2,4],3]];
foo//1
bar//2
baz//3
//例二
let [foo,[[bar],baz]] = [1,[[],3]];
foo//1
bar//undefind
baz//3

从上面的两个例子中可以看出来,如果等号右边的数组对应位置上为空,则等号左边的对应位会被赋值为undefined,如果等号右边有非对应位则不会影响等号左边的值赋值。

如果等号左边为数组而等号右边为非数组(或者不是可遍历的结构)则会报错,下面的例子都会报错

let [foo] = 1;
let [foo] = true;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

上面的例子都会报错,因为等号右边的值或是转为对象以后不具备Iterator接口(前五个表达式),或是本身就不具备Iterator(最后一个表达式)。

对于Set结构,也可以使用数组的解构赋值

let [x,y,z] = new Set(['a','b','c']);
x//'a'

这是因为new Set()对象会返回一个没有重复值的数组,所以具有Iterator接口,都可以采用数组形式的解构赋值。

数组的结构赋值是可以指定默认值的 :

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

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

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

从前两个例子中可以看出来解构赋值实可以指定默认值的,但是第三个传递了值为什么还要使用默认值呢?因为ES6的内部使用严格的 “===”判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的,上面最后一个例子中等号右边第二个值为undefined,所以默认值生效了。

从上面我们知道了,当一个数组成员严格等于undefined时,默认值才会生效,所以当一个数组成员等于null时候不会使用默认值。

let [x] = [null];
x//null

对象的解构赋值

不仅数组可以结构赋值,对象也可以解构赋值,在数组中解构赋值的时候数组的元素时按次序排列的,变量的取值是由它的位置决定的,而对象的属性没有次序,变量必须与属性同名才会赋值。意思就是说:在对象中如果有相同的属性名才有可能赋值,没有相同的属性名就会被赋值为undefined,看下面的两个例子

let {bar,foo} = {foo:"aaa",bar:"bbb"}
foo//aaa
bar//bbb

let {baz} = {foo:"aaa",bar:"bbb"}
baz//undefined

第一个例子说明了对象的解构赋值不用像数组一样来考虑对应位,第二个例子说明了如果没有同名的属性还要解构赋值的话就会被赋值为undefined.

如果变量名的属性名不一样可以写成这样:

let {foo :baz} = {foo:"aaa"}
baz//aaa
foo//undefinde

实际上对象的解构赋值是下面这种形式的简写:

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

也就是说对象的解构赋值的内部机制就是先去找同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者。
上面的代码中foo是匹配机智,baz才是变量,通俗易懂的说就是等号右边的对象先去等号左边找同名属性,然后把等号右边属性值赋值给等号左边的属性值(等号右边的foo先去左边找属性名也是foo的,然后把等号右边的foo对应得属性“aaa"赋值给等号左边foo对应得属性值baz),所以才会出现最后得输出baz 为”aaa“,foo为undefined

和数组一样,对象得结构赋值也可以嵌套

let obj = { p:["hello",{y:"world"}]}
let {p:[x,{y}]}
x//hello
y//world

这里得p是模式,而不是变量,因此不会被赋值,如果想被赋值,也可以写成下面这样:

let obj = { p:["hello",{y:"world"}]}
let {p,p:[x,{y}]}
x//hello
y//world
p//["hello",{y:"world"}]

对象得解构赋值也可以使用默认值

var {x = 3} = {};
x//3
var {x,y = 5} = {x:1}
x//1
y//5

默认值生效得条件也是,对象得属性值严格等于undefined

如果将一个已经声明得变量用于解构赋值,必须注意不能将大括号放在行首,因为如果放在行首JavaScript引擎会将{}理解为一个代码块,从而发生语法错误可已经{}放在()内来避免放在行首这种错误

//错误语法
let x;
{x} = {x:1};

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

字符串得解构赋值

字符串也可以进行解构赋值,因为此时字符串被转换成了一个类似数组得对象。

const [a,b,c,d,e] = "hello"
a//"h"
b//"e"
c//"c"
d//"d"
e//"e"

数值和布尔值的解构赋值

在解析赋值的时候,如果右边是数值和布尔值,则会转为对象

上面的代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

函数参数的解构赋值

函数的参数也可以使用解构赋值,看下面的代码

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

函数add的参数表面上是一个数组,但是在调用的时候传递的是一个数组,此时会发生解构赋值,所以数组的参数会被解构成变量x ,y ,对于函数内部来说,他们能感受到的是x和y.

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

用途

最后我来说一下解构赋值的用途,使用结构赋值可以让我们的代码更加的简化,漂亮。但是前提是要熟练的运用,要不然就会频频报错

1.交换变量的值

在之前我们交换两个变量的值的时候都会声明一个中间变量temp来存放以下,但是使用解构赋值就不需要

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

使用上面的代码来交换两个变量的值是不是比之前的办法更加的简洁!!!

2.从函数中返回多个值

我们知道在函数的返回值中只能是一个变量,一个数组,一个对象,一个布尔值。。。。都是一个的,但是在ES6可以使用解构赋值来使用多个变量来接受函数的返回值。

function xxx(){
   return [1,2,3];
}
let [a,b,c] = xxx()

3.函数参数的定义

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

//参数是一组有序的值
function xxx([x,y,z]){}
xxx([1,2,3]);
//参数是一组无序的值
function xxx({x,y,z}){}
xxx({y:3,z:1,x:2});

4.提取JSON数据

let jsonData = {
    id:42,
    status:"ok",
    data:[857,12]
}
let {id,status,data:number} = jsonData;
console.log(id,status,number)//42,"ok",[857,12]

5.函数参数的默认值

上面写过了

6.遍历Map结构

var map = new Map();
map.set('first','hello');
map.set('second','world');

for(let [key,value] of map){
  console.log(key + "is" + value)
}
//first is hello
//second is world

原文链接 https://zhuanlan.zhihu.com/p/144467498/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容