Javascript 对深度嵌套对象进行空检查的简明方法?
浏览器的JavaScript 我需要测试一个深度嵌入的属性是否不是Javascript 对深度嵌套对象进行空检查的简明方法?,javascript,Javascript,浏览器的JavaScript 我需要测试一个深度嵌入的属性是否不是null,如果此条件为true,则需要更改其属性。但是它的父对象也可以是null。因此,我要检查链中的每个项目。。。所以我写了这么难看的代码: if(window[rootNamespace].vm.tech && window[rootNamespace].vm.tech.currentWorkType && window[rootNamespace].vm.tech.curre
null
,如果此条件为true
,则需要更改其属性。但是它的父对象也可以是null
。因此,我要检查链中的每个项目。。。所以我写了这么难看的代码:
if(window[rootNamespace].vm.tech &&
window[rootNamespace].vm.tech.currentWorkType &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet){
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion
.currentWorkSection.currentStageSet.selectedEntity = item;
}
是否有一种更短的检查方法?语法方面我不这么认为,但我建议至少重构
var getCurrentStageSet = function(window){
return window[rootNamespace].vm.tech &&
window[rootNamespace].vm.tech.currentWorkType &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet
}
var setSelectedEntity = function(currentStageSet, item){
currentStageSet.selectedEntity = item;
}
通过抽象此逻辑,您的实际属性集将更具可读性和可重用性:
var currentStageSet = getCurrentStageSet(window);
if (currentStageSet){
setSelectedEntity(currentStageSet, item);
}
这是基本JavaScript中最简洁的语法。它通过使用错误捕获来避免所有的空检查。其他答案都没有这么简洁,因为该语言只是缺少了您从C#获得的功能 显然,我被其他答案的作者否决了,更不用说简洁的答案了,但这仍然是唯一的一行答案。请注意,此处列出的其他方法甚至可以创建多个函数如果你想要紧凑型,这就是了
try { window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion
.currentWorkSection.currentStageSet.selectedEntity = item; } catch (err) {}
您可以创建一些变量以使代码更具可读性
var tech = window[rootNamespace].vm.tech;
var workType, curVariant, curVer, curWorkSection;
if(tech){
workType = tech.currentWorkType
}
if(workType){
curVariant = workType.currentVariant;
}
if(curVariant){
curVer =curVariant.currentVersion;
}
if(curVer){
curWorkSection = curVer.currentWorkSection;
}
if(curWorkSection && curWorkSection.currentStageSet){
curWorkSection.currentStageSet.selectedEntity = item;
}
对于这样一段琐碎的、自包含的代码,仅仅捕获并忽略错误(可能是日志)可能不是不合理的 不确定在这种类型的检查中还有什么真正的错误,或者你可以捕获一个
TypeError
,但不确定它是否真的那么重要
一般来说,我不推荐“一网打尽”,但在这种情况下,它似乎足够独立,不会成为一个巨大的风险
但是,对于我来说,任何超出这一点的工作都需要付出努力,例如构建对象装饰器或流畅的接口类型解决方案,这似乎有些过头了。(我是最初提出try-catch方法的海报,但根据那篇文章的讨论,您担心性能。这里有一种替代方法。)
可以使用原型方法实现访问子属性的安全方法。以下是一种可以安全测试嵌套属性是否存在的方法:
// Indicates whether an object has the indicated nested subproperty, which may be specified with chained dot notation
// or as separate string arguments.
Object.prototype.hasSubproperty = function() {
if (arguments.length == 0 || typeof(arguments[0]) != 'string') return false;
var properties = arguments[0].indexOf('.') > -1 ? arguments[0].split('.') : arguments;
var current = this;
for(var x = 0; x < properties.length; x++) {
current = current[properties[x]];
if ((typeof current) == 'undefined') return false;
}
return true;
};
//指示对象是否具有指定的嵌套子属性,可以使用链式点表示法指定
//或作为单独的字符串参数。
Object.prototype.hasSubproperty=函数(){
if(arguments.length==0 | | typeof(arguments[0])!='string')返回false;
变量属性=参数[0]。indexOf('.')>-1?参数[0]。拆分('.'):参数;
无功电流=此;
对于(var x=0;x
可以在此处运行,并指出在抛出错误时,使用try-catch方法可能比原始方法运行慢几个数量级,但在其他方面相当快。原型方法更通用,可以产生更具声明性的风格,同时提供比try-catch-misses好得多的性能,但显然不如每次手工编写if语句和/或try-catch-without-misses好
我也知道。不管怎样,你要更改此IMO的可读性会降低。我会让它保持原样。您的根本问题是对象结构。使此代码更具可读性的真正解决方案是修复底层对象。如果它是您自己的对象,则应减少嵌套对象的数量。否则,我同意利亚姆的观点。不,我需要这样的树。C#使用空条件运算符解决它,但javascript中没有任何内容。@Agalo,我知道。我的意思是,你至少可以添加一个简短的解释,同时请我尽量避免生产力的损失,这在异常情况下是不可避免的。@AndreyBushman也许我误解了,但是,如果在原始帖子中键入上面的所有文本,而不是使用错误捕获,您将失去工作效率。试捕对性能的影响应该可以忽略不计。@AndreyBushman您能否详细解释一下您所说的“生产力损失”是什么意思,以及为什么您认为对于例外情况来说这是“不可避免的”。我很好奇。我知道,但第二种选择也不应该被排除在外。我理解您的建议,您当然是对的。我希望存在我不知道的更简洁的语法。这有点夸张。我完全理解并同意这个建议,但我不确定它是如何回答这个问题的-你仍然需要有效地编写相同的代码:/@James我明白你的意思,但我声明它不能简化,这就回答了这个问题。@AndreyBushman这是现在访问子属性的最简洁的方法,没有异常处理,按照请求。。。这是每次访问的单线通话。
// Indicates whether an object has the indicated nested subproperty, which may be specified with chained dot notation
// or as separate string arguments.
Object.prototype.hasSubproperty = function() {
if (arguments.length == 0 || typeof(arguments[0]) != 'string') return false;
var properties = arguments[0].indexOf('.') > -1 ? arguments[0].split('.') : arguments;
var current = this;
for(var x = 0; x < properties.length; x++) {
current = current[properties[x]];
if ((typeof current) == 'undefined') return false;
}
return true;
};