ES6 解構賦值


  解構賦值,就是怎么快速地從對象和數組中獲取到你想要的數據,先來看對象的解構賦值。

let person = {
    name: 'sam',
    age: '28'
};

let {name, age} = person; //  解構賦值
console.log(name, age) // 'sam' 28

  對象字面量的方式聲明了兩個變量name 和age, let {name, age} 放到了等號的左邊, 右邊就是我們要想從中獲取數據的對象。賦值的依據就是對象的屬性,變量名和對象的屬性名一致。對象的解構賦值就是對對象進行分解,從對象中找出和聲明的變量名一致的屬性名,然后把屬性值賦值給對應的變量。這時,也會出現一個問題,當聲明的變量名,在對象中沒有對應的屬性名呢?很簡單,這個變量取值undefined. 

let {job } = person; 
console.log(job) // undefined

  但變量取值undefined, 對以后的計算或操作不太友好,最好給它一個默認值。默認值的賦值方式,也很簡單,使用= 進行賦值。

let {job = 'web' } = person; 
console.log(job) // web

  以上這種解構賦值的方式,還有一個限制,就是聲明的變量名必須和對象的屬性名一致。如果我們已經聲明了一個和對象同名變量,那就不能再聲明這個相同的變量了, 那是不是就不能使用解構賦值了?也不是,就是語法稍微復雜了一點

let {name: localName } = person; 
console.log(localName) // sam

  語法為{對象的屬性名: 聲明變量名}, 意思是獲取到對象中name 屬性對應的值,然后把它賦值給 localName變量,所以,在這種情況下,就不能訪問name了,否則會報錯。當然在這種賦值方式下,也可以提供默認值,因為我們始終是從對象中獲取屬性值,很容易取到對象中沒有的屬性

let {job: localJob = 'web' } = person; 
console.log(localJob) // web

  取person 對象中的job 屬性的值,賦值給localJob 變量,很明顯,賦值的是undefined, 因為person 中沒有job 屬性,localJob 變量也就取值undefined, 有必要給它提供一個默認值。

  以上都是聲明變量,使用解構賦值,其實單純的賦值也可以是使用解構賦值。變量之前就已經聲明了,我們只想給已聲明的變量賦值,那就直接把變量放到大括號里面,放到等號的左邊,右邊放要解構的對象

let person = {
    name: 'sam',
    age: '28'
};

let age = 10;
({age} = person) // 只是賦值,注意要把解構表達式放到小括號里面

  要注意一點,使用解構的方式,只進行賦值操作時,要把整個表達式用小括號括起來。如果不用括號括起來,{age} = person,  第一個{ 會被js 解析為塊級作用域的開始,你不能給一個作用域賦值,所以就會報錯。像{age} = person 這樣的解構賦值表達式,賦值完之后,整個表達式的值仍然是=后面的對象,說起來可能有點不太理解,舉個例子就簡單了

let age = 10;
let obj;
obj = {age} = person;

console.log(age, obj) // 28 { name: 'sam', age: '28' }

  看一下obj ={age} = person;  賦值操作都是從右邊開始計算, 先{age}= person,  person 對象進行解構賦值,然后再賦值給obj. 正如剛才所說,解構賦值表達式最終的結果是=后邊的對象, {age} = person 解構賦值完成以后得到的值是person 對象,然后把person 對象賦值給了obj, 現在obj === person 為true. 如果這樣的話,person的解構賦值也就可以 這樣寫

({age} = {name} = person);

  嵌套對象也可以進行解構,只不過語法看起來有點別扭。

let person = {
    address: {
        province: '廣東',
        city: '深圳'
    }
}

let {address: {province}} = person;
console.log(province)

  person 對象嵌套了address 對象,那怎么找到address 對象中的屬性呢?肯定是先找address 屬性,只有找到它,才能找到它下面的屬性。address 屬性的解構就和普通解構沒有什么區別,let {address} = person.  現在就是向下一步,解析address. 解析address, 無非就是把address 賦值給另外一個解構對象, let {province} = address. address 怎么賦值給別的對象呢? 在解構中使用的是冒號  let {address: anotherAddress} = person.  我們把anotherAddress 換成{province} 又可以了。 let {address: {province}} = person, 沒有問題了。嵌套解構,相當於找到了一個address 屬性, 把它賦值給一個匿名的變量(:右側是要賦值給的目標),正好,這個匿名的變量是一個對象,又可以按照解構的方式取對象里面的屬性值{province} 就產生了。

   對象的解構賦值差不多,再說一下數組的解構賦值。數組是使用數組字面量的方式來解構賦值,也就是說,聲明變量的時候,把變量放在數組字面量中。

let colors = ['red', 'green'];
let [firstColor, secondColor] = colors;

console.log(firstColor, secondColor); // 'red' 'green'

  那數組是怎么實現解構賦值的? 用的是位置或索引,因為數組中,元素的排列都是有順序的,第一個元素就是在數組的第一個位置上,所以聲明變量的時候,第一個變量就對應數組中的第一個位置的元素,第二個變量對應數組中第二位置的元素, firstColor 就對應數組中的第一個值 'red', secondColor 就對應數組中的第二個值'green'.  那如果只想獲取第二個值呢? 第一個變量就不用聲明了,直接寫一個逗號,

let colors = ['red', 'green'];
let [, secondColor] = colors;

console.log( secondColor); // green'

  一個逗號代表的就是一個位置。數組的解構賦值就是位置的一一對應,我們想要數組中哪個元素的值,聲明的變量就要放到哪個位置上,如果這個位置是中間位置,而前面的元素你有不想要,那就用逗號隔開,比如你想要第六位置的元素的值,前面就是5個逗號。

let colors = ['red', 'green'];
let [,,,,, sixColor] = colors;

  當然對於這個例子來說,沒有太大的意義,因為colors 數組只有兩個元素, 第六位置上肯定沒有值。 sixColor 如果沒有獲取到值,肯定是undefined, 這時也可以給它一個默認值。

let [,,,,, sixColor = 'black'] = colors;

  和對象的解構賦值一樣,除了聲明時的解構賦值外,直接給變量賦值也是沒問題的 。

let colors = [ "red", "green", "blue" ];
let firstColor = "black";
let secondColor = "purple";

[ firstColor, secondColor ] = colors;
console.log(firstColor, secondColor); // "red" "green"

  這種解構賦值的方式有一個巨大的作用,我們可以很輕松的交換兩個變量的值。

let x = 1, y = 2;

[y, x] = [x, y];

console.log(x, y); // 2 1

  再來簡單的看一下嵌套數組的解構賦值,一個例子就很明顯了。

let colors = [ "red", [ "green", "lightgreen" ], "blue" ];

let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor, secondColor); // "red" "green"

  數組解構賦值的時候,可以看做把colors 的第二項賦值給一個匿名變量,這個變量正好也是一個數組,順便就再進行一次解構賦值。可以看到嵌套數組的解構賦值,就相當於比着葫蘆畫瓢, 要解構的數組長什么樣,聲明變量的時候所用到的數組格式就長什么樣,只不過它里面放到都是變量,變量和數組元素的一一對應。

  除了和對象的解構賦值相同點之外,數組解構還可以使用... 操作符, 用法和函數的參數使用方法一樣,把剩余的元素收集起來。

let colors = [ "red", "green", "lightgreen" , "blue" ];

let [ firstColor, ...restColor ] = colors;
console.log(firstColor); // "red" 
console.log(restColor); // [ 'green', 'lightgreen', 'blue' ]

  解構賦值的另外一個作用是函數參數的定義,解構賦值的核心就是賦值,只要是賦值的地方,我們都可以用解構賦值表達式。函數的參數正好也是賦值,函數調用的時候就是把實參的值賦值給形參,那么形參的定義,就可以使用解構賦值的聲明變量的方式,原來,我們的形參直接定義一個options , 現在就可以定義成options 要接受的內容。{method, time}

function getRequest(url, {method,time}) {
    
}

  這樣函數的使用就會更加的方便,一看函數聲明就知道傳遞什么參數,還可給它賦值一個默認的參數,這樣函數的運行就更加不會出錯。

function getRequest(url, {method = "get",time = "2000"} = {}) {

}

   解構和重構,這是you don't kown js 中的提到的一個相對高級的用法, 有一個默認的default 配置,就是一個default 的變量。

const defaults = {
  options: {
    remove: true,
    enable: false,
    instance: {}
  },
  log: {
    warn: true,
    error: true
  }
}

  現在有一個配置,就是一個config 變量,它也必須有和default 一樣的格式和屬性,如果config配置中的屬性有值,就使用config 中的值,如果config 屬性中沒有值,就要使用default 中的值進行賦默認值,假設現在config 變量如下:

let config = {
  options: {
    remove: false,
    instance: null
  }
};

  那怎么才能把default 中的值放合並到config 中? 它的做法如下,先對config 進行解構,然后再重建config, 代碼如下

// 最外面的括號聲明的是一個塊級作用域
{
  let {  // 解構賦值
      options: {
      remove = defaults.options.remove,
      enable = defaults.options.enable,
      instance = defaults.options.enable
    } = {},
  
    log: {
      warn = defaults.log.warn,
      error = defaults.log.error
    } = {}
  } = config;

  // restructure 重建
  config = {
    options: { remove, enable, instance },
    log: { warn, error }
  };
}

  稍微解釋一下,先對config 進行解構, let {options: {} = {},  log: {} ={}} = config,  把config中的options 和log 解構出來,為了防止config中沒有options和 log,它用空對象進行了默認值的賦值操作,注意,這個語法不對, 只是為了解釋。然后再對options 和log 又進行了一個解構,options: {remove = defaults.options.remove}, options 中的remove 取出值,如果沒有值,就使用默認值defaults中的值。這時就是聲明了一個remove 變量,它的值先是config 中的remove 屬性值,如果config 中沒有remove屬性,它就使用defaults 中的remove值。其它的enable, instance,  warn, error 也是同樣的道理,它們就是變量。有了變量后,重新組裝了config


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM