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

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

Jan 09, 2025 pm 08:30 PM

[每次突破] 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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

為什麼要將標籤放在的底部? 為什麼要將標籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區問題建議使用支持時區的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標元素,冒泡是從目標元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數設為true實現;2.事件冒泡是默認行為,useCapture設為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態內容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應用戶操作的時機和方式。

JavaScript模塊上的確定JS綜述:ES模塊與COMPORJS JavaScript模塊上的確定JS綜述:ES模塊與COMPORJS Jul 02, 2025 am 01:28 AM

ES模塊和CommonJS的主要區別在於加載方式和使用場景。 1.CommonJS是同步加載,適用於Node.js服務器端環境;2.ES模塊是異步加載,適用於瀏覽器等網絡環境;3.語法上,ES模塊使用import/export,且必須位於頂層作用域,而CommonJS使用require/module.exports,可在運行時動態調用;4.CommonJS廣泛用於舊版Node.js及依賴它的庫如Express,ES模塊則適用於現代前端框架和Node.jsv14 ;5.雖然可混合使用,但容易引發問題

垃圾收集如何在JavaScript中起作用? 垃圾收集如何在JavaScript中起作用? Jul 04, 2025 am 12:42 AM

JavaScript的垃圾回收機制通過標記-清除算法自動管理內存,以減少內存洩漏風險。引擎從根對像出發遍歷並標記活躍對象,未被標記的則被視為垃圾並被清除。例如,當對像不再被引用(如將變量設為null),它將在下一輪迴收中被釋放。常見的內存洩漏原因包括:①未清除的定時器或事件監聽器;②閉包中對外部變量的引用;③全局變量持續持有大量數據。 V8引擎通過分代回收、增量標記、並行/並發回收等策略優化回收效率,降低主線程阻塞時間。開發時應避免不必要的全局引用、及時解除對象關聯,以提升性能與穩定性。

如何在node.js中提出HTTP請求? 如何在node.js中提出HTTP請求? Jul 13, 2025 am 02:18 AM

在Node.js中發起HTTP請求有三種常用方式:使用內置模塊、axios和node-fetch。 1.使用內置的http/https模塊無需依賴,適合基礎場景,但需手動處理數據拼接和錯誤監聽,例如用https.get()獲取數據或通過.write()發送POST請求;2.axios是基於Promise的第三方庫,語法簡潔且功能強大,支持async/await、自動JSON轉換、攔截器等,推薦用於簡化異步請求操作;3.node-fetch提供類似瀏覽器fetch的風格,基於Promise且語法簡單

var vs Let vs const:快速JS綜述解釋器 var vs Let vs const:快速JS綜述解釋器 Jul 02, 2025 am 01:18 AM

var、let和const的區別在於作用域、提升和重複聲明。 1.var是函數作用域,存在變量提升,允許重複聲明;2.let是塊級作用域,存在暫時性死區,不允許重複聲明;3.const也是塊級作用域,必須立即賦值,不可重新賦值,但可修改引用類型的內部值。優先使用const,需改變變量時用let,避免使用var。

為什麼DOM操縱緩慢,如何優化? 為什麼DOM操縱緩慢,如何優化? Jul 01, 2025 am 01:28 AM

操作DOM變慢的主要原因在於重排重繪成本高和訪問效率低。優化方法包括:1.減少訪問次數,緩存讀取值;2.批量處理讀寫操作;3.合併修改,使用文檔片段或隱藏元素;4.避免佈局抖動,集中處理讀寫;5.使用框架或requestAnimationFrame異步更新。

See all articles