賦值解構

目錄:

  1. 數(shù)組的解構賦值
  2. 對象的解構賦值
  3. 字符串的解構賦值
  4. 數(shù)值和布爾值的解構賦值
  5. 函數(shù)參數(shù)的解構賦值
  6. 用途

ES6允許按照一定的模式從數(shù)組和對象中提取值,然后從變量進行賦值,這種方式被稱為解構賦值。

數(shù)組的結構賦值

以前為變量的賦值只能直接指定值

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

在ES6中允許寫成這樣的:let [a,b,c] = [1,2,3] ,這種方式表示可以從數(shù)組中提取值,并按照對應的位置對變量賦值。本質上這種寫法屬于“匹配模式”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應得值,下面是一個嵌套數(shù)組進行解構賦值得例子。

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

從上面得例子中我們可以看到數(shù)組得解構賦值其實是等號兩邊的數(shù)組的相對應位置上的值賦值:請看下面的例子

//例一:
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

從上面的兩個例子中可以看出來,如果等號右邊的數(shù)組對應位置上為空,則等號左邊的對應位會被賦值為undefined,如果等號右邊有非對應位則不會影響等號左邊的值賦值。

如果等號左邊為數(shù)組而等號右邊為非數(shù)組(或者不是可遍歷的結構)則會報錯,下面的例子都會報錯

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

上面的例子都會報錯,因為等號右邊的值或是轉為對象以后不具備Iterator接口(前五個表達式),或是本身就不具備Iterator(最后一個表達式)。

對于Set結構,也可以使用數(shù)組的解構賦值

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

這是因為new Set()對象會返回一個沒有重復值的數(shù)組,所以具有Iterator接口,都可以采用數(shù)組形式的解構賦值。

數(shù)組的結構賦值是可以指定默認值的 :

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的內部使用嚴格的 “===”判斷一個位置是否有值。所以,如果一個數(shù)組成員不嚴格等于undefined,默認值是不會生效的,上面最后一個例子中等號右邊第二個值為undefined,所以默認值生效了。

從上面我們知道了,當一個數(shù)組成員嚴格等于undefined時,默認值才會生效,所以當一個數(shù)組成員等于null時候不會使用默認值。

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

對象的解構賦值

不僅數(shù)組可以結構賦值,對象也可以解構賦值,在數(shù)組中解構賦值的時候數(shù)組的元素時按次序排列的,變量的取值是由它的位置決定的,而對象的屬性沒有次序,變量必須與屬性同名才會賦值。意思就是說:在對象中如果有相同的屬性名才有可能賦值,沒有相同的屬性名就會被賦值為undefined,看下面的兩個例子

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

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

第一個例子說明了對象的解構賦值不用像數(shù)組一樣來考慮對應位,第二個例子說明了如果沒有同名的屬性還要解構賦值的話就會被賦值為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"賦值給等號左邊f(xié)oo對應得屬性值baz),所以才會出現(xiàn)最后得輸出baz 為”aaa“,foo為undefined

和數(shù)組一樣,對象得結構賦值也可以嵌套

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引擎會將{}理解為一個代碼塊,從而發(fā)生語法錯誤可已經{}放在()內來避免放在行首這種錯誤

//錯誤語法
let x;
{x} = {x:1};

//正確語法
let x;
({x} = {x:1})

字符串得解構賦值

字符串也可以進行解構賦值,因為此時字符串被轉換成了一個類似數(shù)組得對象。

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

數(shù)值和布爾值的解構賦值

在解析賦值的時候,如果右邊是數(shù)值和布爾值,則會轉為對象

上面的代碼中,數(shù)值和布爾值的包裝對象都有toString屬性,因此變量s都能取到值。

函數(shù)參數(shù)的解構賦值

函數(shù)的參數(shù)也可以使用解構賦值,看下面的代碼

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

函數(shù)add的參數(shù)表面上是一個數(shù)組,但是在調用的時候傳遞的是一個數(shù)組,此時會發(fā)生解構賦值,所以數(shù)組的參數(shù)會被解構成變量x ,y ,對于函數(shù)內部來說,他們能感受到的是x和y.

函數(shù)參數(shù)的解構賦值也可以使用默認值

用途

最后我來說一下解構賦值的用途,使用結構賦值可以讓我們的代碼更加的簡化,漂亮。但是前提是要熟練的運用,要不然就會頻頻報錯

1.交換變量的值

在之前我們交換兩個變量的值的時候都會聲明一個中間變量temp來存放以下,但是使用解構賦值就不需要

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

使用上面的代碼來交換兩個變量的值是不是比之前的辦法更加的簡潔?。。?/p>

2.從函數(shù)中返回多個值

我們知道在函數(shù)的返回值中只能是一個變量,一個數(shù)組,一個對象,一個布爾值。。。。都是一個的,但是在ES6可以使用解構賦值來使用多個變量來接受函數(shù)的返回值。

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

3.函數(shù)參數(shù)的定義

解構賦值可以很方便的將一組參數(shù)與變量名對應起來

//參數(shù)是一組有序的值
function xxx([x,y,z]){}
xxx([1,2,3]);
//參數(shù)是一組無序的值
function xxx({x,y,z}){}
xxx({y:3,z:1,x:2});

4.提取JSON數(shù)據(jù)

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.函數(shù)參數(shù)的默認值

上面寫過了

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/

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容