浏览器的JavaScript
我需要测试一个深度嵌入的属性不是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;
}
是否有较短的检查方法?
答案 0 :(得分:1)
语法明智我不这么认为,但我建议至少重构。
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);
}
答案 1 :(得分:1)
(我是提出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;
};
A full set of methods can be found here, with sample code.
Timings可以在这里运行,并指出使用 try-catch方法在抛出错误时可能会比原始方法运行几个数量级,但是否则非常快。原型方法更通用,可以产生更具声明性的风格,同时提供比try-catch未命中更好的性能,但显然不如手工制作每次if语句和/或try-catch而不会错过。
答案 2 :(得分:0)
对于这样一个微不足道的,自包含的代码,只是捕获并忽略错误(可能是日志)可能并非不合理,例如。
try {
if (window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet) {
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet = item;
}
} catch (e) {
// log the error but continue
}
不确定在这种类型的支票中还有什么可能真的出错,或者你可以专门捕捉TypeError
,但不确定它真的会那么重要。
我一般不会建议赶上所有人,但在这种情况下,它似乎自足,不会成为巨大的风险。
除此之外的任何事情都需要努力,例如建立一个对象装饰器或一个流畅的接口类型解决方案,但对我来说似乎有点过分了。
答案 3 :(得分:-1)
您可以创建一些变量以使代码更具可读性
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;
}
答案 4 :(得分:-2)
这是基本JavaScript中最紧凑的语法。它通过使用错误捕获来避免所有空值检查。没有其他答案是紧凑的,因为语言只是缺少你在C#之后的功能。
显然,我被其他人的作者拒绝了,而不是紧凑的答案,但这仍然是唯一的单行答案。请注意,此处列出的其他方法可让您创建多个功能。 :|如果你想要紧凑,就是这样。
try { window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion
.currentWorkSection.currentStageSet.selectedEntity = item; } catch (err) {}