首頁 > web前端 > js教程 > [每次突破] JavaScript 如何判斷屬性是否存在

[每次突破] JavaScript 如何判斷屬性是否存在

Barbara Streisand
發布: 2025-01-09 20:30:45
原創
302 人瀏覽過

[每次突破] JavaScript 如何判断属性是否存在

前言

在 JavaScript 開發中,我們常常需要判斷在於一個物件中一個屬性是否存在。
由於 JavaScript 是比較鬆散的語言,導致我們很難去做一些比較嚴格的事。就例如這個問題,「屬性是否存在」在 JavaScript 的定義出現了偏差,到底什麼時候是存在,什麼是算不存在。這沒有對錯之分,只是在不同的脈絡下,不同的開發需求下,「存在」的意思是不一樣的。
這裡我就說一說比較常用的5種判斷方式,和它們存在的問題。

方法 1:布爾(Boolean)判定

這裡舉個例子:

const obj1 = { name: 'Andy', age: 21 }
const obj2 = { name: 'Alice' }

console.log( obj1.age ? '存在' : '不存在' ); // 存在
console.log( obj2.age ? '存在' : '不存在' ); // 不存在
登入後複製
登入後複製

先說說這種方式的缺陷吧
如果:

const obj = { name: 'Baby', age: 0 }

console.log( obj.age ? '存在' : '不存在' ); // 不存在
登入後複製
登入後複製

這種情況下,age應是 “存在”,但是會被判斷成“不存在”。

那麼這種方式是不是就不能用呢?
這就要根據業務的開發需求了。
如果你知道在你的業務開發需求裡,這個屬性是不可能為0,空字串啊,NaN啊,undefined之類的,那麼這個判定還是可行的。
如果你放在更嚴格的環境,那麼這個方式就有缺陷的。

方法 2: 可選鏈 (?.) 和 undefined 檢查

還是先舉例:

const obj1 = { name: 'Andy', age: 21 }
const obj2 = { name: 'Alice' }

console.log( obj1?.age !== undefined ? '存在' : '不存在' ); // 存在
console.log( obj2?.age !== undefined ? '存在' : '不存在' ); // 不存在
登入後複製
登入後複製

這個對比的邏輯就是,在JS語言裡,一個不存在的值就是undefined。

但是在一個物件裡,也可能出現的這種情況:

const obj = {
    name: 'Andy',
    age: undefined
}
登入後複製
登入後複製

像這種情況,那麼age這個屬性應該是「存在」呢,還是「不存在」?

這也就不好說了,還是要看你的具體的需求環境。

方法 3: 找出Object.keys()

如果說,我就要知道一個物件裡有沒有一個屬性age,我不管它的值是什麼。

我們就可以用這個方式:

const obj = { name: 'Andy', age: 21 }

console.log( Object.keys(obj).includes('age') ? '存在' : '不存在' ); // 存在
登入後複製
登入後複製

使用Object.keys()可以得到自身的可列舉屬性名稱來進行判斷。

這裡有兩個關鍵字,一個是「自身的」(own),一個是「可列舉」(enumerable)。

首先說,什麼是“自身的”

比方說這裡有一個對象,給對象加一個屬性name:

const obj = { name: 'Andy' }
// `name` 就是 obj 自身的属性
console.log( Object.keys(obj) ); // [ 'name' ]
登入後複製

那麼什麼不是自身的屬性呢?這裡就要扯到「原型」了。一個物件是有原型,在原型上加的屬​​性就不是「自身的」屬性了。

const obj = Object.create( { type: 'human' } );
obj.name = 'Andy';

console.log( obj.name ); // Andy
console.log( obj.type ); // human
console.log( Object.keys(obj) ); // [ 'name' ]
登入後複製

這個例子,你怎麼判斷type是不是obj的屬性呢?這就不好說了對吧,你可以說是,也可以說不是。這就是語言寬鬆環境所帶來的問題。

但你要知道的是,在這種情況下,Object.keys()是拿不到原型上的屬性。因為它只能讀取“自身的”屬性。

第二個是,“可枚舉”

這裡就要提到屬性描述符了,我很多同事都不知道,在JS語言裡,在一個物件裡,每個屬性都有一個描述符的。
怎麼讀取呢?我們印一下看:

const obj1 = { name: 'Andy', age: 21 }
const obj2 = { name: 'Alice' }

console.log( obj1.age ? '存在' : '不存在' ); // 存在
console.log( obj2.age ? '存在' : '不存在' ); // 不存在
登入後複製
登入後複製

你會發現,這個描述符其實也是一個對象,它描述了這個屬性的一些信息,比如說值(value),可重寫(writable),還有這個(enumerable)可枚舉 ...

這個enumerable定義了那個屬性,是否可以被列舉,例如for...in迴圈時候可以讀取這個屬性,Object.keys()也是如此。

如果我重新定義一個屬性為不可枚舉的,那麼Object.keys()就讀取不到這個屬性了。

const obj = { name: 'Baby', age: 0 }

console.log( obj.age ? '存在' : '不存在' ); // 不存在
登入後複製
登入後複製

這裡就涉及到了屬性描述符的相關知識了,這個是原生JS語言非常重要的知識,而我發現很多我認識的前端程式設計師都缺乏這種原生JS的知識。

那麼如果說你要判斷的屬性要求只要是自身的屬性,不管可不可枚舉呢?那就不能用Object.keys()了。可以用接下來的方法。

方法 4:使用 Object.hasOwn() 或 hasOwnProperty()

Object.hasOwn() 和 hasOwnProperty() 有什麼差別呢?

Object.hasOwn() 是 ES2022 加入的方法,用來檢查物件是否本身俱有某個屬性,用於取代 hasOwnProperty 的促優處理。由於這是後來加入的方法,相容性還是個問題,如果只考慮新版本的瀏覽器還是可以用的。

這兩個方法判斷的是 「自身的」 屬性名,所以不管是不是可枚舉,都能被讀取。

const obj1 = { name: 'Andy', age: 21 }
const obj2 = { name: 'Alice' }

console.log( obj1?.age !== undefined ? '存在' : '不存在' ); // 存在
console.log( obj2?.age !== undefined ? '存在' : '不存在' ); // 不存在
登入後複製
登入後複製

為什麼要用Object.hasOwn(),由於物件的hasOwnProperty()有可能被修改:

const obj = {
    name: 'Andy',
    age: undefined
}
登入後複製
登入後複製

如果你要判斷的屬性名,不要求是自身的和可枚舉,原型也行,那麼就要用最後一個方法了。

方法 5: in 運算符

in 運算子用來判斷一個屬性是否存在於物件或其原型鏈中。

const obj = { name: 'Andy', age: 21 }

console.log( Object.keys(obj).includes('age') ? '存在' : '不存在' ); // 存在
登入後複製
登入後複製

總結

這些方法種,沒有說那個方法是正確的,那個錯誤的。並不是每個場景都適合同一種方法,根據情況遵守最佳實踐,以增強程式碼可讀性和安全性。

以上是[每次突破] JavaScript 如何判斷屬性是否存在的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板