Released 2023-08-02

Modified 2023-08-03

Tech

1249Words (7min read)

JavaScript 檢驗物件是否包含屬性的方法

Title Image

Photo by JavaScript on JavaScript

導言 - Lead paragraph

在 JavaScript 開發中,經常需要判斷一個物件是否包含特定屬性。

下面將介紹幾種常用且效能良好的方法,幫助開發者更好地處理這類需求。

在 ECMAScript 2022 (ES13) 以前,有兩種較多人使用的傳統方法可以檢查 JS 對象是否具有任何自定義屬性:

  • in operator
  • hasOwnProperty() function

而在 ES13 的 “hasOwn()” 出現以後,正式自 ECMAScript 2022(ES13) 起,就不再需要使用 hasOwnProperty() 了,因為我們可以使用新的內置 Object.hasOwn() 方法。

in 運算符 - in Operator

這是 JavaScript 中內建的運算子,可以檢查物件是否包含指定的屬性,包括直接擁有的和透過原型鏈繼承的屬性。

const obj = { name: 'John', age: 30 };

console.log('name' in obj);
console.log('gender' in obj);

// Output:
// true
// false 

Object.hasOwn()

⚠️ Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()

如果指定的對象自身有指定的屬性,則返回 true。如果屬性是繼承的或者不存在,該方法返回 false。

它與 in 運算符不同,因為它不檢查繼承的屬性。

const obj = { name: 'John', age: 30 };

console.log(Object.hasOwn(obj, 'name'));
console.log(Object.hasOwn(obj, 'gender'));

// Output:
// true
// false 

官方文檔:Object.hasOwn() - JavaScript | MDN

Object.prototype.hasOwnProperty()

已過時,但還可使用

這是 JavaScript 中內建的方法,可用於檢查物件自身是否包含指定的屬性,而不是透過原型鏈繼承而來的屬性。

const obj = { name: 'John', age: 30 };

console.log(obj.hasOwnProperty('name'));
console.log(obj.hasOwnProperty('gender'));

// Output:
// true
// false 

Object.keys()

使用 Object.keys() 將物件的屬性名稱轉換為一個陣列,然後可以透過陣列的方法來判斷是否包含指定的屬性。

const obj = { name: 'John', age: 30 };

console.log(Object.keys(obj).includes('name'));
console.log(Object.keys(obj).includes('gender'));

// Output:
// true
// false 

Object.prototype.hasOwnProperty.call()

這是 hasOwnProperty() 的一個變種,可以解決某些特殊情況下的問題,特別是當物件的 hasOwnProperty() 被覆寫時。

const obj = { name: 'John', age: 30 };

console.log(Object.prototype.hasOwnProperty.call(obj, 'name'));
console.log(Object.prototype.hasOwnProperty.call(obj, 'gender'));

// Output:
// true
// false 

Object.getOwnPropertyNames()

Object.getOwnPropertyNames() 會返回物件本身所有屬性(不包括繼承的屬性)的名稱,可以用來檢查是否存在指定屬性。

const obj = { name: 'John', age: 30 };

console.log(Object.getOwnPropertyNames(obj).includes('name'));
console.log(Object.getOwnPropertyNames(obj).includes('gender'));

// Output:
// true
// false 

undefined OR !==

這是一種比較老式的方法,在現代 JavaScript 中不太常見,但仍然有效。

通過檢查屬性是否等於 undefined,來判斷物件是否包含指定的屬性。

const obj = { name: 'John', age: 30 };

console.log(obj.name !== undefined);
console.log(obj.gender !== undefined);

// Output:
// true
// false 

方法與使用情境對比

方法使用情境
in 運算符檢查物件是否包含指定屬性,包括原型鏈中的屬性。
需要考慮物件及其原型鏈中是否有指定屬性時使用。
Object.prototype.hasOwn()指定對象具有指定屬性作為其自己的屬性。
只需要判斷物件自身是否擁有指定屬性時使用。
Object.prototype.hasOwnProperty()檢查物件是否包含指定屬性,且不考慮原型鏈繼承。
只需要判斷物件自身是否擁有指定屬性時使用。
Object.keys()將物件的屬性名稱轉換為陣列,方便進行遍歷或其他陣列方法。
不需關心屬性的值,只需判斷是否存在時使用。
Object.getOwnPropertyNames()獲得物件本身所有屬性(不包括繼承的屬性)的名稱。
只需檢查物件本身的屬性時使用。
Object.prototype.hasOwnProperty.call()hasOwnProperty 的變種,解決某些特殊情況下的問題。
可以用在 hasOwnProperty 方法被覆寫時。

這些方法在不同的使用情境中有不同的優勢。

選擇適合的方法取決於需求以及是否需要考慮物件的原型鏈。

看到很多文章都使用 hasOwnProperty()in 運算符,ChatGPT 也推薦使用兩者擇一,原因是因為它們的效能相對較好且用法直觀。

但是 ChatGPT GPT-3.5 架構,其訓練數據截止日期為 2021 年 9 月。

並沒有涵蓋到 ECMAScript 2022(ES13)的 hasOwn() 問世資訊,經過查閱大量文章、教學與實測後,使用 hasOwn() 會比 hasOwnProperty() 好。

若只需判斷物件自身是否擁有指定屬性,較簡單的情況下可以選擇 hasOwn();若需考慮原型鏈中的屬性,則選擇 in 運算符。

Object.keys()Object.getOwnPropertyNames() 通常用於需要操作物件所有屬性名稱的場景,但不需關心屬性值本身。

Object.prototype.hasOwnProperty.call() 主要用於解決特殊情況下的問題,不常使用,但了解它可以解決覆寫 hasOwnProperty() 的問題,但 Object.hasOwn() 直接克服了這些問題,因此是首選。。

結論 - Concluding

開發者可以根據需求選擇適合的方法,提高程式效率。

參考資料 - Reference

[1] ChatGPT

https://chat.openai.com/

[2] The Difference Between in and hasOwnProperty in JavaScript - Mastering JS

https://masteringjs.io/tutorials/fundamentals/hasownproperty

[3] JavaScript: hasOwn() — new way to check if Object has property | by Igor Gonchar | Medium

https://igorgonchar.medium.com/javascript-hasown-new-way-to-check-if-object-has-property-b93810e47070

[4] 檢驗物件是否包含屬性 - Google Search

https://www.google.com/search?q=%E6%AA%A2%E9%A9%97%E7%89%A9%E4%BB%B6%E6%98%AF%E5%90%A6%E5%8C%85%E5%90%AB%E5%B1%AC%E6%80%A7

JavaScript 檢驗物件是否包含屬性的方法

https:///en/blog/81

Author

Kama

Read more from Tech
lightbox-image
Toggle Button - Red Pandas Icons by svgrepo.com

Copyrights © 2023 Kama, All Rights Reserved.