如何高效检查JavaScript对象中的键是否存在

程序员咋不秃头2024-07-09 16:08:08  106

在日常开发中,作为一个JavaScript开发者,我们经常需要检查对象中某个键是否存在。这看似简单,但其实有多种方法可供选择,每种方法都有其独特之处。本文将介绍几种检查JavaScript对象键的方法,并比较它们的性能。

问题背景

假设我们有一个简单的对象:

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

我们想在访问name键之前检查它是否存在:

if (user.name) { console.log(user.name); }

这个方法表面上看没问题,但如果name键存在但值是undefined会怎样呢?

const user = { name: undefined};if (user.name) { // 这段代码不会执行!}

直接访问一个不存在的键会返回undefined,但是访问值为undefined的键也是返回undefined。所以我们不能依赖直接键访问来检查键是否存在。

使用typeof

一种常见的方法是使用typeof来检查类型:

if (typeof user.name !== 'undefined') { console.log(user.name);}

typeof会对不存在的键返回"undefined",对存在的键返回其它类型,如"string"。然而,这种方法有几个缺点:

需要额外的操作(typeof)而不是直接比较

比较冗长且需要否定检查(!==)

可读性不如其他方法

容易拼写错误'undefined'

使用in操作符

in操作符允许我们检查键是否存在于对象中:

if ('name' in user) { console.log(user.name); }

这种方法比typeof更简洁:

简单且可读

内置语言特性,专为此设计

对所有值都有效,包括undefined

但是,in操作符也会检查对象的原型链。因此它对原型链上存在的键也会返回true。

使用hasOwnProperty

要仅检查对象自身的键,可以使用hasOwnProperty:

if (user.hasOwnProperty('name')) { console.log(user.name);}

这种方法只会返回对象自身拥有的键,而不会检查继承的属性:

只检查自身键,不包括继承的

方法名清晰,容易理解

缺点是hasOwnProperty需要方法调用,在性能关键的代码中可能会有影响。

性能比较

哪种方法最快呢?以下是直接键访问、in、hasOwnProperty和typeof的简单性能比较:

const user = { name: 'John' };let key = 'name';function directAccess { return user[key] !== undefined; }function inOperator { return key in user;}function hasOwnProperty { return user.hasOwnProperty(key);}function typeofCheck { return typeof user[key] !== 'undefined';}function objectKeysCheck { return Object.keys(user).includes(key);}// 运行每个函数100万次let start = performance.now;for (let i = 0; i < 1000000; i++) { directAccess;}console.log(`directAccess took ${performance.now - start} ms`);start = performance.now;for (let i = 0; i < 1000000; i++) { inOperator;}console.log(`inOperator took ${performance.now - start} ms`);start = performance.now;for (let i = 0; i < 1000000; i++) { hasOwnProperty;}console.log(`hasOwnProperty took ${performance.now - start} ms`);start = performance.now;for (let i = 0; i < 1000000; i++) { typeofCheck;}console.log(`typeofCheck took ${performance.now - start} ms`);start = performance.now;for (let i = 0; i < 1000000; i++) { objectKeysCheck;}console.log(`objectKeysCheck took ${performance.now - start} ms`);

结果如下( 测试机器:apple m1 ,内存16G):

directAccess耗时 1.59 毫秒

inOperator 耗时 0.97 毫秒(注:inOperator 和 typeofCheck 有时会比较接近)

hasOwnProperty耗时 4.74 毫秒

typeofCheck耗时 1.16 毫秒

Object.keys耗时 8.48 毫秒

如上所示,inOperator 运算显著快于其他方法。

总结

直接键访问较快且易读但无法处理undefined值

in操作符最快但能处理所有值,包括undefined

hasOwnProperty较慢但只检查对象自身的键

typeof速度较快但需要冗长的否定检查

Object.keys方法直观,但速度最慢

在大多数情况下,in操作符在可读性和性能之间提供了最佳平衡。只有在需要排除继承键时才使用hasOwnProperty。

理解这些不同方法的细微差别是检查JavaScript键的关键。根据具体需求选择合适的工具,除非性能至关重要,否则应优先考虑可读性。

转载此文是出于传递更多信息目的。若来源标注错误或侵犯了您的合法权益,请与本站联系,我们将及时更正、删除、谢谢。
https://www.414w.com/read/889682.html
0
随机主题
哈尔斯: 公司是可口可乐的杯具授权商, 用于制造联名款水杯辽篮夺冠谁是最大功臣?弗格无缘前四,第一名你应该想不到!难道不想看看房地产股票的业绩吗? 没有业绩涨上去, 也是空涨哦被注射抑生长剂, 皮肤溃烂无人管, 这3位童星, 真的被父母害惨了盖丽丽:多才艺术家绿色地球授予认证北冕号在内的全部庞洛邮轮旗下船只球王待遇!超远任意球还得2人堵门,盐湖城为了防梅西真的是绞尽脑汁英国国防大臣称: 欧洲的中立国如果还想得到保护, 就必须加入北约1894年, 18岁珍妃因得罪慈禧, 惨遭扒裤羞辱, 激烈反抗终致命丧黄泉有了“福建舰”后,中国还需要几艘航母,才能战胜美国海军?各地应合理制定年度土储计划, 资金专款专用!梦幻西游:老王光环队开启牟利模式,1小时竟能刷这么多?真强!全新凯迪拉克XT5要来了, 或5月27日上市, 换装9K曲面屏, 外观升级没有社媒的小因扎吉通过妻子账号告别张康阳: 谢谢你米体: 两位独立董事将辞职, 马洛塔&安东内洛有望留在国米董事会《狐妖月红篇》发布会: 杨幂拘谨放不开, 胡连馨颜值出挑拜仁新帅只差官宣!38岁降级队教练登陆豪门,5大豪门拒绝穆里尼奥低配渡江芙蓉枪! 平民玩家的不二选择!求新、求变的《梦幻西游》追求的是有血有肉的角色!4年2.94亿! 亚历山大解锁超级续约资格 合同年薪突破8000万大关彻底卖不动了? iPhone在中国跌出前五, 华为成最大赢家
最新回复(0)