.hasOwnProperty()
使用物件的 prototype hasOwnProperty
檢查。
不會遍歷原型鏈。
const profile = {
name: 'Sean',
age: 24,
}
profile.hasOwnProperty('name') // true
profile.hasOwnProperty('valueOf') // false
const profile = {
name: 'Sean',
age: 24,
}
profile.hasOwnProperty('name') // true
profile.hasOwnProperty('valueOf') // false
in
最簡潔的寫法,使用關鍵字 in
檢查。
但請留意 in
會去尋找整個原型鏈,可能得到預期外的結果,並造成微乎其微的效能差異。
const profile = {
name: 'Sean',
age: 24,
}
'name' in profile // true
// ⚠️
// 雖然以下 key 沒有在 `profile` 中明確定義,
// 但因為它們存在於物件的 prototype 中,
// 所以依然會得到 true。
'valueOf' in profile // true
'toString' in profile // true
const profile = {
name: 'Sean',
age: 24,
}
'name' in profile // true
// ⚠️
// 雖然以下 key 沒有在 `profile` 中明確定義,
// 但因為它們存在於物件的 prototype 中,
// 所以依然會得到 true。
'valueOf' in profile // true
'toString' in profile // true
Object.prototype.hasOwnProperty.call()
由於 JavaScript 未保護 hasOwnProperty
,所以你完全可以直接複寫這個屬性,讓它刻意回傳錯誤的結果。
const profile = {
name: 'Sean',
age: 24,
hasOwnProperty: () => true,
}
// 😢 永遠都會得到 true
profile.hasOwnProperty('🍺') // true
profile.hasOwnProperty(123456789) // true
const profile = {
name: 'Sean',
age: 24,
hasOwnProperty: () => true,
}
// 😢 永遠都會得到 true
profile.hasOwnProperty('🍺') // true
profile.hasOwnProperty(123456789) // true
利用 Object.prototype.hasOwnProperty.call()
即可避免此情況發生。
// 😎 雖然冗長但較安全
Object.prototype.hasOwnProperty.call(profile, '🍺') // false
Object.prototype.hasOwnProperty.call(profile, 'name') // true
// 😎 雖然冗長但較安全
Object.prototype.hasOwnProperty.call(profile, '🍺') // false
Object.prototype.hasOwnProperty.call(profile, 'name') // true
Object.keys().includes()
先以 Object.keys()
取得物件的所有 key 的陣列,接著呼叫陣列的方法 includes()
來檢查 key 是否存在。
不會遍歷原型鏈。
const profile = {
name: 'Sean',
age: 24,
}
const keys = Object.keys(profile) // ['name', 'age']
keys.includes('name') // true
keys.includes('valueOf') // false
const profile = {
name: 'Sean',
age: 24,
}
const keys = Object.keys(profile) // ['name', 'age']
keys.includes('name') // true
keys.includes('valueOf') // false
⚠️ 其他常見方法,但小心有陷阱
!== undefined
當試圖存取不存在於物件的 key 時,會得到 undefined
。
但當某 key 存在,而且值剛好是 undefined
時,那就仍會得到 false
。
const profile = {
name: 'Sean',
phone: undefined,
}
profile['address'] !== undefined // false
profile['phone'] !== undefined // ⚠️ false
const profile = {
name: 'Sean',
phone: undefined,
}
profile['address'] !== undefined // false
profile['phone'] !== undefined // ⚠️ false
!!
或 Boolean()
👎
簡單暴力的寫法,也就是直接將值轉型成 boolean。
但這顯然是相對不可靠的方法,因為只要是 falsy 值,例如 0
、空字串 ''
、 null
等 ,即使 key 存在但依然會得到 false
。
除非你可以保證物件的值的型別,例如在有使用 TypeScript 的場合,否則並不推薦這寫法。
const profile = {
name: 'Sean',
balance: 0,
isDead: false,
}
!!profile['name'] // true
// ⚠️
!!profile['balance'] // false
Boolean(profile['isDead']) // false
const profile = {
name: 'Sean',
balance: 0,
isDead: false,
}
!!profile['name'] // true
// ⚠️
!!profile['balance'] // false
Boolean(profile['isDead']) // false