通俗易懂理解ES6 - 變量的解構賦值

引言

萬丈高樓平地起,欲練此功,必先打好基本功: )


編程語言總少不了變量賦值;ES6中引入了新的賦值形式:__解構賦值__;解構賦值大大的簡化了變量賦值的代碼,解構賦值僅能對具備迭代器(Iterator)的數據使用;javascript

什麼是迭代器(Iterator)?這有兩篇文章能夠參考一下(對閱讀下文會有幫助):html

我本人對iterator的總結理解java

阮一峯老師寫的極客學院文章es6


賦值和解構賦值

__解構賦值__,直白地理解就是 __解析解構__,__進行賦值__~

在ES5中,咱們對變量的賦值是這樣的編程

var a = {item: 'obj',item1: 'obj1'},
    b = ['c1','c2','c3'],
    c = 'test',
    d = 'test2'
var item = b.item,
    item1 = b.item1,
    item2 = b.item2,
    arrItem = c[0],
    arrItem1 = c[1];
item;       //obj
item1;      //obj1
item2;      //undefined
arrItem;    //c1
arrItem1;   //c2

emmmmm...好麻煩~

再看看使用ES6解構賦值的寫法:數組

let a = {item: 'obj',item1: 'obj1'},
    b = ['c1','c2','c3'];
let {item,item1,item2} = a,
    [arrItem,arrItem1] = b,
    [,,arrItem2,arrItem3] = b;
item;       //obj
item1;      //obj1
item2;      //undefined
arrItem;    //c1
arrItem1;   //c2
arrItem2;   //c3

沒有對比就沒有傷害,使用解構賦值能夠在必定程度上減小代碼量,且代碼賦值形式簡潔、直觀;解構賦值不只適用於let命令,constvar一樣適用。編程語言

解構賦值僅容許等號右邊的對象是存在遍歷器(Iterator)的對象。 以下是錯誤的解構賦值示例:函數

let [item] = 1;
let [item] = {};
let [item] = NaN;
let [item] = null;
let [item] = false;
let [item] = undefined;

解構賦值容許賦值時對變量指定默認值。post

//ES5
let obj = {item1: 'test'},
    item1 = obj.item1,
    item2 = obj.item2;
item2;      //空字符串
    
//ES6
let obj = {item1: 'test'},
    { item1='',item2='' } = obj;
item2;      //空字符串

比對ES5的賦值形式和ES6的解構賦值,變量item2在ES5的賦值形式下,因爲obj不存在item2屬性,致使item2獲得undefined的值,而ES6的解構賦值,可在賦值進行時對變量預留默認值,避免賦值的變量獲得undefined的值;它的效果可理解爲

ui

let item1 = obj.item1 || '',
    item2 = obj.item2 || '';

解構賦值在解構失敗時,若變量沒有預留默認值,獲得的值也會是undefined。

let obj = {a: 'string'},
    [b,c] = ['test'],
    {d} = obj;
b;      //test
c;      //undefined
d;      //undefined

以上狀況就是個別變量存在解構失敗的示例,變量b對應的是test,c無對應值,obj.d不存在,且cd未設置默認值,所以cd解構失敗,獲得的值就爲undefined

當且僅當變量對應的取值的數據爲undefined時,默認值纔會生效

let a = {b: null},
   {b='test'} = a;
b;  // null
let [c='test'] = [undefined];
c;  //test
let [d='test',e='www'] = [NaN,null];
d;  //NaN
e;  //null

ES6內部使用嚴格相等符===判斷一個值是否等於undefined,當且僅當值是undefined,默認值纔會生效。

若解構賦值中,指定的默認值是一個函數表達式,則該表達式當且僅當在用到的時候纔會求值

let fn = () => {
    return '123';
};
let [a=fn(),b=fn()] = [1];
a;      //1
b;      //123

在某些場合下,解構賦值也能夠將某些對象的方法簡便命名調用

let { assign, freeze } = Object;
let a = assign({},{b:1}),
    b = freeze(a);
a;      //{b: 1}
b;      //{b: 1}

將一個已被變量聲明過的變量用於解構賦值時,須要把解構賦值表達式放在()內

let a = 'test';
{a} = {a: 'obj test'};          //報錯:Uncaught SyntaxError: Unexpected token =
({a} = {a: 'obj test'});        //a等於  obj test

這是由於在JavaScript解釋的過程當中,行首是"{"的話,JavaScript會把"{}"包起來的代碼解釋爲一個代碼塊,致使語法錯誤;而咱們實際須要執行的是{a} = {a: 'obj test'}這樣整個賦值過程,所以須要用"()"包起來,避免{出如今行首。

對對象進行解構賦值時,不要求變量名必須與屬性名一致,但命名賦值方式會稍有區別

let man = {name:'john',sex:'male',height:'177cm',weight:'70kg',interest:'climbing'};
let {name: mans_name,sex:sexal,height:tall,job:works='u guess'} = man;
mans_name;      //john
sexal;          //male
tall;           //177cm
works;          //u guess
name;           //Uncaught ReferenceError: name is not defined

let {name: mans_name} = man;表明將man.name的值賦值給變量名爲mans_name的變量,其餘變量同理,該賦值形式一樣能夠設置默認值,如變量works;

解構賦值適用於函數參數

function Human({name='',sex='female',age}) {
    if(sex==='male') {
        console.log('u must be a handsome guys!');
    }else if(sex === 'female') {
        console.log('u must be a beauty!');
    }else {
        console.log('exm,r u seriouse?');
    }
    console.log(name);
    console.log(sex);
    console.log)(age);
}
let character = {sex:'male',name:'Allen',age:27}
Human(character); 
//  u must be a handsome guys!
//  Allen
//  male
//  27

當參數爲undefined時,也會觸發默認值生效,如sex參數,當不傳sex參數時,sex會獲得默認值female

解構賦值一樣適用於字符串

let [a,b,c,d] = 'test',
a;          //t
b;          //e
c;          //s
d;          //t

解構賦值時,若等號右側是一個字符串形式的值,解構賦值的處理操做會把右側字符串轉變成相似數組形式的解構進行對變量的解構賦值。
數組對象都具備length屬性,所以類數組的對象也必須具備length屬性,以下代碼塊也一樣成功執行賦值。

let {length: len} = 'test';
len;        //4

對數值類型和布爾型數據進行解構賦值

let {a,toString} = 123;
a;      //undefined
toString === Number.prototype.toString;      //true

let {b,toString} = true;
b;      //undefined
toString === Boolean.prototype.toString;     //true

上述兩個示例,右側的值因爲可被對象化(Number、Boolean),對象化後均存在toString屬性,所以toString變量等同於相應右側值對象化後的prototype.toString方法。而a、b均是對象化後不存在的屬性,所以獲得的值就爲undefined。

解構賦值的規則是,等號右側如果對象類型,則直接進行解構賦值,若不是對象類型,會把對象類型轉換爲對象類型,再進行解構賦值,轉換失敗,解構賦值失敗。


解構賦值的多功能用途

解構賦值能簡化變量交換值

let a = 1,b = 2;
[a,b] = [b,a];
a;          //2
b;          //1

解構賦值簡化對函數返回值取值操做

function test() {
    return {a:'a',b:'b',c:'c'};
};
let {a,b,c} = test();
a;      //a
b;      //b
c;      //c

解構賦值簡化鍵值數據獲取方式和數據賦值容錯寫法

let map = new Map();
map.set('test','javacript').set('do','something');
for(let [key,value] of map) {
   console.log(key + ' ' + value);
}
//test javascript
//do something

let obj = {},
   {a='本來是undefined,如今是有個這個字符串的值'} = obj;
a;     //本來是undefined,如今是有個這個字符串的值

對import、require引入的模塊加載指定的方法或數據

import {Ajax_Interface,Format_Interface} from '~/Interface_Configs.js';
const {RouterConfigs, PageConfigs} = require('Common-Configs');


## 對解構賦值的一些總結

ES6提供的解構賦值讓賦值操做變得更具備可讀性,對變量能預留默認值,避免數據操做過程當中由undefined所致使的一些報錯狀況。把解構賦值用於函數參數處理上,有效避免參數無序傳入致使取參麻煩的問題。

以上。

文章觀點內容若有錯誤歡迎指出交流,相互進步

相關文章
相關標籤/搜索