在 JavaScript 中,是不是有更简单的方法来检查属性的属性是不是存在?
Posted
技术标签:
【中文标题】在 JavaScript 中,是不是有更简单的方法来检查属性的属性是不是存在?【英文标题】:In JavaScript, is there an easier way to check if a property of a property exists?在 JavaScript 中,是否有更简单的方法来检查属性的属性是否存在? 【发布时间】:2011-10-03 15:01:17 【问题描述】:有没有一种简单的方法来原生地确定 javascript 中的对象中是否存在深层属性?例如,我需要访问这样的属性:
var myVal = appData.foo.bar.setting;
但有可能 foo、foo.bar 或 foo.bar.setting 尚未定义。在 Groovy 中,我们可以这样做:
def myVal = appData?.foo?.bar?.setting
在 JavaScript 中是否有类似的方法可以做到这一点,而无需编写自定义函数或嵌套 if 语句?我发现this answer 很有用,但希望有一种更优雅、更少自定义的方式。
【问题讨论】:
遵守得墨忒耳法则之外,没有。 我多么希望我们在 C# 中有那个运算符... v8.dev/features/optional-chaining 【参考方案1】:我觉得这很方便:
var myVal = (myVal=appData) && (myVal=myVal.foo) && (myVal=myVal.bar) && myVal.settings;
如果存在属性,将尝试序列的下一部分。
当&&
之前的表达式计算结果为假时,将不检查表达式的下一部分。如果未定义myVal.appData.foo.bar.settings
中的任何一个,则myVal
(undefined
( 的值将计算为false
。
【讨论】:
请注意,这种方法对于深度嵌套的变量非常有用。当变量由两个名字组成时,如foo.bar
,myVal = foo && foo.bar
更方便。
括号内的那些“子任务”没有理由。 JavaScript 返回序列最后一个表达式的实际值,否则返回false
。它不会像其他具有类似短路运算符的语言那样将值强制为布尔值。
@Pointy:子分配是为了避免重复属性名称,以便整体代码长度为 O(N) 而不是 O(N^2)。我自己会尝试在长度开始重要时切换到自定义函数。
@Pointy var myVal = appData && foo && bar && settings
不会产生预期的结果。请参阅我之前的评论。
不,但我认为尖的意思是:var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.settings;
。如果 var 名称不长,实际上我更喜欢这种方式。但如果它们很长,我更喜欢你的方式,Rob。不管怎样,我喜欢它。 +1【参考方案2】:
抱歉,不太好:
var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.setting;
另一种选择:
try
var myVal = appData.foo.bar.setting;
catch (e)
var myVal = undefined;
.运算符并不是真正用于访问这样的对象。可能使用函数是个好主意。
【讨论】:
【参考方案3】:我发现其他方法有点庞大。那么,以下方法的主要缺点是什么:
// Pass the path as a string, parse it, and try to traverse the chain.
Object.prototype.pathExists = function(path)
var members = path.split(".");
var currentMember = this;
for (var i = 0; i < members.length; i++)
// Here we need to take special care of possible method
// calls and arrays, but I am too lazy to write it down.
if (currentMember.hasOwnProperty(members[i]))
currentMember = currentMember[members[i]];
else
return false;
return true;
基本上,我们在对象上定义一个方法(不一定),该方法获取嵌套对象的路径并返回存在确认,如appData.pathExists("foo.bar.setting");
编辑:
检查object[prop] == undefined
在语义上不正确,因为即使定义了属性,尽管它的值为undefined
,它也会返回false;这就是为什么我使用hasOwnProperty
来检查是否定义了属性。如果只需要获取值,这可能并不重要。
【讨论】:
【参考方案4】:如果,之后:
var myVal = appData.foo && appData.foo.bar && appData.foo.bar.setting;
myVal
不是undefined
,它将保存appData.foo.bar.setting
的值。
【讨论】:
【参考方案5】:你可以试试这个
var x = y:z:a:'b'
x && x.y && x.y.z && x.y.z.a //returns 'b'
这不如 groovy 表达式好,但它有效。遇到第一个未定义的变量后,评估停止。
【讨论】:
【参考方案6】:var product = ...,
offering = (product||).offering,
merchant = (offering||).merchant,
merchantName = (merchant||).name;
if (merchantName)
displayMerchantName(merchantName);
http://osteele.com/archives/2007/12/cheap-monads
【讨论】:
【参考方案7】:我刚刚做了这个,所以它可能无法完全正确地工作,我还包含了两个测试用例。
function hasPropertyChain(o, properties)
var i = 0,
currentPropertyChain = o;
if(!o)
return false;
while(currentPropertyChain = currentPropertyChain[properties[i++]]);
return i - 1 === properties.length;
alert(hasPropertyChain(a:b:c:'a', ['a','b','c'])); // true
alert(hasPropertyChain(a:b:c:'a', ['a','b','c', 'd'])); // false
【讨论】:
以上是关于在 JavaScript 中,是不是有更简单的方法来检查属性的属性是不是存在?的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP.NET 核心中创建 JWT 是不是有更简单的方法?又名“JWT 身份验证的最佳实践?”
我们在 JavaScript 中有更简单的三元运算符吗? [复制]
是否有更简单的方法在 Roblox (Lua) 上的父对象中查找对象