JSON未定义属性-简化验证以避免TypeErrors

时间:2019-02-07 20:09:59

标签: javascript json properties undefined simplify

我正在尝试有效地验证多层json对象,这些对象可能会根据情况具有一个或多个未定义的父属性。

这是一个示例,仅对象2个级别的属性:

    scenarioArray = [ 
    {color:{blue:'yes'}},
    {color:{green:'no'}},
    {colour:{blue:'yes'}} ]; //colour instead of color

所以我想最有效地识别场景的颜色


    let color;
    let s = randomScenario; //random scenario from the scenarioArray
    if(s.color != undefined && s.color.blue != undefined){
        color = s.color.blue;
    }else if (s.color != undefined && s.color.green != undefined){
        color = s.color.green;
    }else if (s.colour != undefined && s.colour.blue !=undefined){
        color = s.colour.blue;
    };

此代码在技术上有效,只是一团糟。

将其外推到具有4-5个级别的属性的对象时,if语句变得笨拙且不可读。

我很乐意就如何简单地提出建议。

现实世界中的json对象示例:

    addendum.contract.buyerInformation.name 
    addendum.contract.contract.buyerInformation.name
    addendum.contract.purchaser.buyerFirstName
    addendum.contract.data.purchaser.buyer.name

使用的框架/库: AngularJS 洛达 (向所有建议的库开放,这些库也可以提高效率)

P.S。请让我知道这是否太开放了,以至于stackOverflow ...

2 个答案:

答案 0 :(得分:0)

这是一个可以为您找到错误的函数。它最多支持三个级别。它是可配置的。对于第4级和第5级,您可以扩展它或使其递归以获得无限级别的支持:

Kotlin

答案 1 :(得分:0)

不幸的是,JavaScript缺乏本机autovivification,但可以通过Proxy进行某种程度的仿真。

这是一个笨拙且易碎的解决方案,但是它将任何深度检查减少为两个操作,并且在大多数情况下应该可以使用:

'use strict';

const isEmpty = Symbol('isEmpty');

function autoVivify(object = {}) {
  Object.defineProperty(object, isEmpty, {
    get: () => Object.keys(object).length === 0,
  });

  Object.keys(object).forEach((key) => {
    const val = object[key];
    if (typeof val === 'object' && val !== null) object[key] = autoVivify(val);
  });

  return new Proxy(
    object,
    { get: (obj, name) => name in obj ? obj[name] : obj[name] = autoVivify() },
  );
}

const scenarioArray = [
    { color: { blue: 'yes' }},
    { color: { green: 'no' }},
    { colour: { blue: 'yes' }},
];

const randomScenario = autoVivify(scenarioArray[0]);

if (randomScenario.color.blue && !randomScenario.color.blue[isEmpty])
  console.log(randomScenario.color.blue);

if (randomScenario.color.red && !randomScenario.color.red[isEmpty])
  console.log(randomScenario.color.red);

if (randomScenario.color.a.b.c && !randomScenario.color.a.b.c[isEmpty])
  console.log(randomScenario.color.a.b.c);

if (randomScenario.colour.green && !randomScenario.colour.green[isEmpty])
  console.log(randomScenario.colour.blue);

希望我们很快就会有a more appropriate way