1. 程式人生 > 其它 >JavaScript 解構用法解析

JavaScript 解構用法解析

一. 基本概念

ES6(ES2015)的釋出,給JavaScript 提供了一種更方便快捷的方式來處理物件或陣列的屬性。該機制稱為Destructuring(也稱為解構賦值)。

下面就來看看什麼是解構賦值。MDN 中對解構賦值的描述:

 

解構賦值語法是一種 Javascript 表示式。通過解構賦值, 可以將屬性值從物件/陣列中取出,賦值給其他變

量。

 

實際上,結構賦值就是將複雜的結構分解為簡單的部分。解構賦值語法可以用於變數宣告或者變數賦值。除此之外,還可以使用巢狀的解構賦值語法來處理巢狀結構。

二. 解構分類

 

根據MDN對解構賦值的定義,我們可以將解構賦值分為兩大類:

  1. 物件解構
  2. 陣列解構

 

三. 物件的解構賦值

1.物件中獲取值

物件解構又稱為物件屬性分配模式,它允許我們將物件的屬性值分配給相應的變數。它有兩種寫法:

let obj =  {x: 1, y: 2, z: 3};

let {x, y, z} = obj;
console.log(x, y, z)

let {x: a, y: b, z: c} = obj;  // 別名
console.log(a, b, c)

第1種 是物件解構的簡寫形式,物件的屬性與要分配的屬性一致時可以使用這種形式;

第2種 是物件解構的完整形式,物件的每個屬性都將被分配一個變數,其中冒號前面的是源物件中的屬性,冒號後面的是要賦值屬性(其實類似於是用別名)。

2. 預設值與新變數

當然我們在日常開發的過程中,可能會遇到很多極端的情況,例如後端傳過來的物件,可能會缺失某些欄位:

const person = {
    name: 'ZhangSan',
    height: 180,
    age: undefined, // 只有undefined可以 null 0 都不行
};

const { name, height, age = 25,  gender = '男'} = person;

console.log(name, height, age, gender);  // ZhangSan 180 25 男

這裡我們給age分配了一個預設值,當對源物件上不存在age屬性時,age就會被賦上預設值25,而不是undefined。

如果分配的物件屬性為undefined,那麼就會使用預設值

const {x = 2} = {x: undefined};
console.log(x);    // 2

四. 陣列的解構賦值

在使用陣列解構時,實際上會使用迭代器將所需要的值與結構源分開。因此,我們可以對可迭代值使用陣列結構,包括字串、陣列、集合、函式對映、DOM元素。我們還可以將解構賦值與擴充套件運算子結合使用。

1.字串

let message = 'Hello';
let [a, b] = message;
let [x, y, ...z] = message;

console.log(a, b);        // H e
console.log(x, y, z);     // H e ['l', 'l', 'o']

2.陣列

let numbers = [1, 2, 3];
let [x, y, z] = numbers;

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

3.集合

let set = new Set().add('foo').add('bar');
let [a, b] = set;

console.log(a, b);      // foo bar

4.Map

let map = new Map().set('a', 1).set('b', 2);
let [x, y] = map;

console.log(x, y);    // ["a", 1] ["b", 2]

5.Tips

在陣列的解構中,儲存變數的陣列中的每個變數都會對映到解構陣列上相同索引處的相應項。

如果解構中某一項不需要,可以使用逗號操作符進行分隔:

const rgb = [200, 255, 100];

const [,, blue] = rgb;

console.log(blue);   // 100

與物件解構一樣,可以使用陣列解構為區域性變數設定預設值

const rgb = [200];

const [red = 255, green, blue = 255] = rgb;

console.log(`R: ${red}, G: ${green}, B: ${blue}`);

如果變數已經存在,就可以這麼寫:

let red = 100, green = 200, blue = 50;

const rgb = [200, 255, 100];

[red, green] = rgb;

console.log(`R: ${red}, G: ${green}, B: ${blue}`);

物件解構不同的是,這裡不需要括號將陣列括起來。

如果給變數分配的值是undefined,那麼就會使用預設值:

const [x = 1] = [undefined];
console.log(x);    // 1

這裡的預設值並不一定是一個固定值,它可以是一個計算屬性:

function foo() {
    return 1;
}

let obj1 = {x: 2};
let obj2 = {x: undefined};

let {x=foo()} = obj1;
console.log(x);     // 2

let {x=foo()} = obj2;
console.log(x);     // 1

如果我們想將陣列中的一些元素分配給變數,而將陣列中的其餘項分配給特定的變數就可以這樣做:

let [greeting,...intro] = ["Hello", "I" , "am", "CUGGZ"];

console.log(greeting);  // "Hello"
console.log(intro);     // ["I", "am", "CUGGZ"]

五. 巢狀解構

實際上,解構賦值可以用於巢狀陣列和巢狀物件

1.解構巢狀物件

const student = {
    name: 'ZhangSan',
    age: 18,
    scores: {
        math: 19,
        english: 85,
        chinese: 100
    }
};

const { name, scores: {math, english, chinese} } = student; 

2.解構巢狀陣列

let numbers = [1, [2, 3, 4], 5];
let [a, [b, c, d], e] = numbers;
console.log(a, b, c, d, e); // 1 2 3 4 5

六. 使用技巧

1.函式解構

(1)解構函式傳參

使用物件解構將屬性值作為引數傳遞給函式。

function foo([a, b]) {
    console.log(a + b);
}
foo([1, 2]);       // 3


function bar({x, y}) {
    console.log(x, y);
}
foo({x: 1, y: 2}); // 1 2

(2)解構函式物件返回值

物件解構函式還有另一種用法。如果函式返回一個物件,您可以將值直接解構為變數。讓我們建立一個返回物件的函式

function getStudentInfo() {
    return {
        name: 'ZhangSan',
        age: 18,
        scores: {
            math: 19,
            english: 85,
            chinese: 100
        }
    };
}
const { name, scores: {math, english, chinese} } = getStudentInfo();
console.log(name, math, english, chinese);

2.迴圈中解構

我們想要遍歷陣列並想要使用每個員工物件的屬性值

const User= [
  { 
       'name': '路人甲',
   		 'age': 16
  },
  { 
      'name': '路人乙',
   		 'age': 18
  },
  { 
        'name': '路人丙',
   		 'age': 20
  }
];

您可以使用for-of迴圈遍歷User物件,然後使用物件解構賦值語法來檢索詳細資訊。

for(let {name, age} of User) {
  console.log(`${name} 今年${age}歲!!!`);
}
// 路人甲 今年16歲!!!
// 路人乙 今年18歲!!!
// 路人丙 今年20歲!!!

3.動態屬性解構

很多時候我們不知道物件屬性的key,只有執行時才知道。比如有一個方法getStudentInfo,它以一個key為引數,並返回相應的屬性值:

getStudentInfo('name'); 
getStudentInfo('age'); 

這裡傳遞給getStudentInfo方法的引數是動態的,因此可以這樣寫:

const getStudentInfo = key => {
  const {[key]: value} = student;
  return value;
}

需要注意,包裹key的方括號不能少,否則會出現undefined值。

4.交換變數

陣列結構一個很實用的功能就是實現交換區域性變數。通常,我們會藉助臨時變數來實現變數的交換

let width = 300;
let height = 400;

let temp = width;
width = height;
height = temp;

console.log(width, height)

如果使用陣列的解構賦值,就會變得很簡單:

let width = 300;
let height = 400;

[width, height] = [height, width];

console.log(width, height)

5.陣列拷貝

可以使用解構賦值和rest運算子來實現陣列的拷貝:

const rgb = [200, 255, 100];

const [...newRgb] = rgb;
// 等同於 const newRgb = [...rgb]

console.log(newRgb)