Object.keys 和 Object.entries 用法

Object.keysObject.entries 是 JavaScript 中處理物件的兩個非常實用的靜態方法,它們提供了不同方式來遍歷和處理物件的屬性。讓我詳細解釋這兩個方法的用法、差異和實際應用場景。

Object.keys()

基本語法

Object.keys(obj)

功能說明

  • 返回一個字串陣列,包含物件自身所有可枚舉屬性的名稱(鍵)

  • 返回的陣列順序與使用 for...in 循環遍歷該物件時返回的順序相同

返回類型

  • 返回值是一個字串陣列 string[]

使用範例

const person = {
  name: '王小明',
  age: 30,
  city: '台北'
};

const keys = Object.keys(person);
console.log(keys); // 輸出: ['name', 'age', 'city']

// 用於檢查物件是否為空
if (Object.keys(person).length === 0) {
  console.log('物件為空');
}

// 用於遍歷物件屬性
Object.keys(person).forEach(key => {
  console.log(`${key}: ${person[key]}`);
});
// 輸出:
// name: 王小明
// age: 30
// city: 台北

Object.entries()

基本語法

Object.entries(obj)

功能說明

  • 返回一個陣列,包含物件自身所有可枚舉屬性的 [key, value] 對陣列

  • 每個項目是一個長度為 2 的陣列,第一個元素是屬性名(鍵),第二個元素是屬性值

  • 返回的陣列順序與 Object.keys() 相同

返回類型

  • 返回值是一個二維陣列 [string, any][]

使用範例

const person = {
  name: '王小明',
  age: 30,
  city: '台北'
};

const entries = Object.entries(person);
console.log(entries);
// 輸出: [['name', '王小明'], ['age', 30], ['city', '台北']]

// 用於解構賦值遍歷
for (const [key, value] of Object.entries(person)) {
  console.log(`${key}: ${value}`);
}
// 輸出:
// name: 王小明
// age: 30
// city: 台北

// 結合 map 進行資料轉換
const formattedData = Object.entries(person).map(([key, value]) => {
  return {
    fieldName: key,
    fieldValue: value
  };
});
console.log(formattedData);
// 輸出: [
//   { fieldName: 'name', fieldValue: '王小明' },
//   { fieldName: 'age', fieldValue: 30 },
//   { fieldName: 'city', fieldValue: '台北' }
// ]

主要差異

  1. 返回值結構:

    • Object.keys: 只返回屬性名的陣列

    • Object.entries: 返回 [key, value] 對的陣列

  2. 使用場景:

    • Object.keys: 當你只需要屬性名時使用

    • Object.entries: 當你同時需要屬性名和屬性值時使用

在你的程式碼中的應用

在你提供的程式碼中,這兩個方法被用於不同目的:

Object.keys 的使用

if (Object.keys(this.yColumnValueList[0]).length > 0) {
  this.previousYValues = { ...this.yColumnValueList[0] };
}

這裡 Object.keys 用於檢查 this.yColumnValueList[0] 物件是否有任何屬性。如果有屬性(長度大於 0),則保存當前值作為先前值。

Object.entries 的使用

const inputs: Input[] = Object.entries(formData).map(([key, value]) => ({
  modelColumnId: key as string,
  value: value as string,
}));

這裡 Object.entries 用於將表單數據轉換為 API 所需的格式。它提取每個屬性的鍵值對,然後使用解構賦值和 map 方法將它們轉換為所需的物件格式。

實用技巧與範例

1. 物件轉換

將一個物件的鍵全部轉為大寫:

const obj = { name: '小明', age: 30 };
const upperObj = Object.entries(obj).reduce((acc, [key, value]) => {
  acc[key.toUpperCase()] = value;
  return acc;
}, {});
console.log(upperObj); // { NAME: '小明', AGE: 30 }

2. 物件過濾

過濾掉物件中值為 null 或 undefined 的屬性:

const obj = { name: '小明', age: null, city: '台北', address: undefined };
const filtered = Object.entries(obj)
  .filter(([_, value]) => value !== null && value !== undefined)
  .reduce((acc, [key, value]) => {
    acc[key] = value;
    return acc;
  }, {});
console.log(filtered); // { name: '小明', city: '台北' }

3. 統計分析

計算物件中數值屬性的總和:

const scores = { math: 90, english: 85, science: 95 };
const total = Object.values(scores).reduce((sum, score) => sum + score, 0);
console.log(total); // 270

4. 物件比較

比較兩個物件的差異:

const oldData = { name: '小明', age: 29, city: '台北' };
const newData = { name: '小明', age: 30, country: '台灣' };

// 找出被修改的屬性
const modified = Object.keys(oldData)
  .filter(key => newData.hasOwnProperty(key) && oldData[key] !== newData[key])
  .reduce((acc, key) => {
    acc[key] = { old: oldData[key], new: newData[key] };
    return acc;
  }, {});

// 找出新增的屬性
const added = Object.keys(newData)
  .filter(key => !oldData.hasOwnProperty(key))
  .reduce((acc, key) => {
    acc[key] = newData[key];
    return acc;
  }, {});

// 找出刪除的屬性
const removed = Object.keys(oldData)
  .filter(key => !newData.hasOwnProperty(key))
  .reduce((acc, key) => {
    acc[key] = oldData[key];
    return acc;
  }, {});

console.log('修改:', modified); // { age: { old: 29, new: 30 } }
console.log('新增:', added);    // { country: '台灣' }
console.log('刪除:', removed);  // { city: '台北' }

總結

  • Object.keys: 當你只需要物件的屬性名稱時使用,返回 string[]

  • Object.entries: 當你需要同時處理屬性名和屬性值時使用,返回 [string, any][]

這兩個方法在現代 JavaScript/TypeScript 開發中非常常見,特別是在處理表單數據、API 響應、狀態管理和數據轉換時,能顯著簡化程式碼並提高可讀性。

Last updated