ES6非常棒的特性-解構

好的代碼實踐

我們有一個方法:buildAnimal(),它需要三個參數:accessory, animal, color。

<code>

function

buildAnimal

(

accessory, animal, color

)

{...}

1

/<code>

然後我們需要加一個參數,我們需要怎麼做?很簡單啊,直接在方法名後面加不就好了嗎。

但是我們是好的程序員,怎麼能這麼沒追求啊是不是:

“Functions should have a small number of arguments. No argument is best, followed by one, two, and three. More than three is very questionable and should be avoided with prejudice.”Robert C. Martin’s Clean Code

我們開始重構,把所有的參數放到一個對象裡面:animalData,它有下面三個屬性:animal, color, hairType

<code>

function

buildAnimal

(

animalData

)

{...}

1

/<code>

如果要加參數,直接加到animalData的屬性裡面就好了。但是,又有一個問題了。如果我們要衝對象裡面拿數據:可能要這樣:

<code> 

function

buildAnimal(animalData){

let

accessory = animalData.accessory,

animal

=

animalData.animal,

color

=

animalData.color,

hairType

=

animalData.hairType;

...

}1234567

/<code>

代碼重複了很多,很不優雅對不對!

解構

先定義一個對象:

<code>

let

obj = { accessory:

'horn'

, animal:

'horse'

, color:

'purple'

, hairType:

'curly'

}123456/<code>

解構的原理是:從一個對象一次性解析出多個屬性給不同變量,比如數組中解析出元素,從map/set中解析出數據等。

模式

任何結構都有兩個部分1 解構源: 等號右邊是要解構的對象。2 解構目標:等號左邊是要解構的對象。

對象解構(解構源)

上面的例子,解構的寫法可以這樣:

<code>

function

buildAnimal

(

animalData

)

{

let

{accessory, animal, color, hairType} = animalData; ... }

1234

/<code>

animalData的對象屬性給到變量:accessory, animal, color, hairType

<code>

console

.log(accessory);

//

horn

console

.log(animal);

//

horse ... 你可能要問,如果是多層嵌套的對象怎麼解構? 比如: ```

let

person = {

name

:

'Maya'

,

age

:

30

,

phone

:

'123'

,

address

:{

zipcode

:

1234

,

street

:

'rainbow'

,

number

:

42

} }

class

=

"se-preview-section-delimiter"

>

div

>

12345678910111213141516171819202122

我們可以這麼做:

<code>

let

{

address

: {zipcode, street, number}} = person;

console

.log(zipcode, street, number);

<

div

class

=

"se-preview-section-delimiter"

>

div

>

12345678

/<code>

或者:

<code>

let

{zipcode, street, number} = person.address;

console

.log(zipcode, street, number);

<

div

class

=

"se-preview-section-delimiter"

>

div

>

12345678

/<code>

可能有人說我們需要,我們的變量名需要和屬性名一樣。實際上不需要。我們可以重新修改它的名字:比如

<code>

let

{

name

: fullName} = person;

console

.log(fullName);

console

.log(name);

<

div

class

=

"se-preview-section-delimiter"

>

div

>

123456789

/<code>

解構數組

比如我們定義這樣一個數組:

<code>

var

arr = [

"one"

,

"two"

,

"three"

,

"four"

];

class=

"se-preview-section-delimiter"

>

1234567

/<code>

這一次我們左邊就不能用{},而應該用[]:

<code>

var

[first, second] = arr;

var

[,,third, four] = arr;

var

[one, two, three, four] = arr

class

=

"se-preview-section-delimiter"

>

div

>

123456789

說明:如果不要解構某一個元素,直接逗號隔開就行了,參考:【行2】。要注意的是逗號的位置和數量。解構嵌套數組:

<code>

var

arr2 = [[

'one'

,

'two'

],

'three'

,

'four'

];

var

[[one, two]] = arr2;

class=

"se-preview-section-delimiter"

>

12345678

/<code>

解構可遍歷的對象:比如Map,Set,字符串等

<code>

var

[a, b] =

new

Set

([

1

,

2

]);

var

[a, b] =

new

Map

([[

1

,

2

], [

2

,

3

]]);

var

[x, y] =

"xyz"

;

<

div

class

=

"se-preview-section-delimiter"

>

div

>

123456789

/<code>

解構賦值

多個變量的聲明和初始化:

<code>

let

a,

b,

c,

d;

a

=

2

;

b

=

3

;

c

=

{

id:

4

};

d

=

5

;

//Or:

let

a

=

2

,

b

=

3

,

c

=

{

id:

4

},

d

=

5

;

class="se-preview-section-delimiter">

123456789101112

/<code>

解構賦值的話,我們可以這麼寫:

<code>

let

a,

b,

c,

d;

[a,

b,

c,

d]

=

[2,

3

,

{

id:

4

},

5

];

//Or:

let

[a,

b,

c,

d]

=

[2,

3

,

{

id:

4

},

5

];

class="se-preview-section-delimiter">

123456789

/<code>

解構帶上默認值

如果我們要解構的對象的屬性沒有值,甚至屬性不存在。這個時候,我們需要一個默認值:通常我們可能會這麼寫:

<code>

let

name = person.name ||

"default name"

;

class=

"se-preview-section-delimiter"

>

1234567

/<code>

在解構裡面,我們可以這麼寫:

<code>

let

{name =

"default name"

} = obj;

class=

"se-preview-section-delimiter"

>

1234567

/<code>

如果屬性不存在,name 會被賦值一個默認的值。或者:

<code>

let

{name: myFullName =

"default name"

} = obj;

class=

"se-preview-section-delimiter"

>

1234567

/<code>

如果屬性不存在,myFullName 會被賦值一個默認的值。

多參數: …操作符

比方說我們有一個數組,我們想要數組的第一個元素,剩餘的元素用作其他用途。一般我們會這麼寫:

<code>

let

first = arr[

0

], rest = arr.slice(

1

);

class=

"se-preview-section-delimiter"

>

12345678

/<code>

ES6解構我們可以這麼寫:

<code>

let

[first, ...rest] = arr;

console

.log(first);

console

.log(rest);

<

div

class

=

"se-preview-section-delimiter"

>

div

>

123456789

/<code>

注意:…操作符只能放到最後。

<code>

let

[...rest, last] = arr;

class=

"se-preview-section-delimiter"

>

12345678

/<code>

交換

<code>

function

swap

(

arr, i, j

)

{

let

temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }

class

=

"se-preview-section-delimiter"

>

div

>

1234567891011

我們經常會有上面的交換兩個元素的代碼。有了解構以後,我們可以這麼寫:

<code>

function

swap

(

arr, i, j

)

{ [arr[i], arr[j]] = [arr[j], arr[i]]; }

class

=

"se-preview-section-delimiter"

>

div

>

123456789

解構在函數中的好處

在上面的例子中,我們是這麼做的:

<code>

function

buildAnimal

(

animalData

)

{

let

{accessory, animal, color, hairType} = animalData;

console

.log(

`I'm a

${color}

${animal}

with

${accessory}

and

${hairType}

hair`

}; }

class

=

"se-preview-section-delimiter"

>

div

>

12345678910

實際上,我們希望直接從參數列表裡解構出來:

<code>function buildAnimal({accessory, animal, color, hairType}}{...}




<

div

class

=

"se-preview-section-delimiter"

>

div

>

1234567/<code>

甚至可以定義默認值:

<code>

function

buildAnimal

(

{accessory =

""

, animal =

"cat"

, color =

'rainbow'

, hairType =

'straight'

}

)

{...}

class

=

"se-preview-section-delimiter"

>

div

>

1234567

調用的方式這樣:

<code>buildAnimal({accessory = 

"horn"

, animal =

"horse"

, color =

'purple'

, hairType =

'curly'

}};

class=

"se-preview-section-delimiter"

>

12345678

/<code>

注意一點:如果我們要默認參數,我們需要傳遞一個對象進去:

<code>buildAnimal({});  
buildAnimal();  




class=

"se-preview-section-delimiter"

>

12345678

/<code>

我們能不傳遞一個空對象嗎?可以。

<code>

function

buildAnimal

(

{accessory =

""

, animal =

"cat"

, color =

'rainbow'

, hairType =

'straight'

} = {}

)

{...}

class

=

"se-preview-section-delimiter"

>

div

>

1234567

我們給我們的參數一個默認的值:{}

數組也是類似:

<code>

function

sum

(

[a =

0

, b =

0

, c =

0

]=[]

)

{

return

a + b + c;}

console

.log(sum([

1

,

2

,

3

]));

console

.log(sum());

<

div

class

=

"se-preview-section-delimiter"

>

div

>

123456789

/<code>

解構不好的地方

1 我們不能解構,如果沒有采用聲明的語法,或者()包起來因為解構是以{}開頭,而{}在JavaScript中當做一個塊,而不是對象常量。

<code>

let

a,

b;

{a,

b}

=

{a:

1

,

b:

2

};

//Error!!!

({a,b})

=

{a:

1

,

b:

2

};

//Error!!

({a,

b}

=

{a:

1

,

b:

2

});

//OK1234

/<code>

2 嵌套對象的屬性必須存在否則會解構失敗

<code> 

1

我們不能解構,如果沒有采用聲明的語法,或者()包起來

因為解構是以{}開頭,而{}在JavaScript中當做一個塊,而不是對象常量。

```javascript

let

a,

b;

{a,

b}

=

{a:

1

,

b:

2

};

//Error!!!

({a,b})

=

{a:

1

,

b:

2

};

//Error!!

({a,

b}

=

{a:

1

,

b:

2

});

//OK12345678

/<code>

以上就是今天的主要內容,感謝閱讀。

ES6非常棒的特性-解構

收藏

舉報

小生編程Loading.../<code>
/<code>

掃碼下載今日頭條

/<code>
/<code>
/<code>
/<code>

javascriptperson = {:{} }

/<code>


分享到:


相關文章: