Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对深度嵌套对象进行空检查的简明方法?_Javascript - Fatal编程技术网

Javascript 对深度嵌套对象进行空检查的简明方法?

Javascript 对深度嵌套对象进行空检查的简明方法?,javascript,Javascript,浏览器的JavaScript 我需要测试一个深度嵌入的属性是否不是null,如果此条件为true,则需要更改其属性。但是它的父对象也可以是null。因此,我要检查链中的每个项目。。。所以我写了这么难看的代码: if(window[rootNamespace].vm.tech && window[rootNamespace].vm.tech.currentWorkType && window[rootNamespace].vm.tech.curre

浏览器的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;
}

是否有一种更短的检查方法?

语法方面我不这么认为,但我建议至少重构

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;
};