Проверить целостность сложного объекта JavaScript - PullRequest
1 голос
/ 13 мая 2011

Как лучше всего проверить целостность сложного объекта в JavaScript?

Мой объект имеет кучу разных переменных, некоторые необязательные, некоторые обязательные. Правильная структура жизненно важна для функциональности кода, но если я ошибусь во время определения, поиск точного значения, вызвавшего проблему, может стать очень утомительным. Особенно с сообщениями об ошибках, которые говорят мне не более, чем «Где-то в коде, вы используете неправильный тип переменной!».

Мой объект может выглядеть примерно так, например:

{
  name:"Test",
  categories:{
    A:{
      depth:1,
      groups:{
        main:[
          {myFunction:funcA, arg:[1,2]},
          {myFunction:funcB}
        ]
      }
    },
    B:{
      groups{
        main:[
          {myFunction:funcC}
        ],
        secondary:[
          {myFunction:funcD}           
        ]
      }
    }
  }
}

Спасибо!

Ответы [ 4 ]

4 голосов
/ 13 мая 2011

Нет хорошего способа сделать это, кроме написания функции, которая получает объект в качестве входных данных и проверяет, что он имеет «правильную» структуру.

function isValid(obj)
{
    if (!o) return false;
    if (typeof o.name !== 'string') return false;
    if (typeof o.categories !== 'object') return false;
    if (typeof o.categories.a !== 'object') return false;
    if (typeof o.categories.b !== 'object') return false;
    // etc...

    return true;
}

С другой стороны, выможет определить конструктор, который принимает любые аргументы, необходимые для правильного построения объекта.

function MyObj(name, categoryNames /* other args */)
{
    this.name = name;
    this.categories = {};

    for (var i=0; i<categoryNames.length; i++)
    {
        this.categories[categoryNames[i]] =
        {
            groups: {main: []}
        };
    }

    // etc
}

// use it like this:
var foo = new MyObj('Test', ['A', 'B'] /* other args */);
0 голосов
/ 20 мая 2011

Хорошо, вот как я это решил: я создаю объект, который определяет, как должны выглядеть мои сложные объекты. Проект, в некотором смысле.

var structure = {
  property1: {id:"name", type:"string", required:false},
  property2: {
    id:"categories", type:"object", required:true,
    content:{
      property1:{
        type:"object", min:1,
        content:{
          property1:{id:"depth", type:"positiveinteger", required:false},
          property2:{
            id:"groups", type:"object", required:true,
            content:{
              property1:{
                type:"array", min:1,
                content:{
                  type:"object", min:1,
                  content:{
                    property1:{id:"myFunction", type:"function", required:true},
                    property2:{id:"args", type:"array", required:false},
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Затем я запускаю функцию, которая сравнивает проект ("struct") с объектом, который будет проверен ("def"):

function compareStructure(struct, def){
  if(isArray(def)){
    if(isDefined(struct.min) && def.length < struct.min){ alert("Error in structur check: " + " min is " + struct.min + "."); return false}
    if(isDefined(struct.max) && def.length > struct.max){ alert("Error in structur check: " + " max is " + struct.max + "."); return false}
    for(var i = 0; i < def.length; i++){
      compareStructure(struct.content, def[i]);
    }
  } else {
    for(var k in struct){
      if(struct[k].id){
        propFound = false;
        for(var m in def) if(m == struct[k].id) propFound = m;
        if(!propFound && struct[k].required){ alert("Error in structure check:  " + struct[k].id + " not defined."); return false}
        if(propFound && !verifyThis(struct[k], def[propFound], propFound)) return false;
        if(propFound && struct[k].content) compareStructure(struct[k].content, def[propFound]);
      } else {
        for(var m in def){
          if(!verifyThis(struct[k], def[m], m)) return false;
          if(struct[k].content) compareStructure(struct[k].content, def[m]);
        }
      }
    }
  }
}

function verifyThis(struct, def, prop){
  // This is where the checks for types and values are made.
}

Функция сравнения все еще находится в стадии разработки, но сейчас я использую эту концепцию.

0 голосов
/ 13 мая 2011

Вы можете попробовать Проверка схемы JSON . Вам может потребоваться внести некоторые изменения, чтобы учесть тот факт, что у вас также могут быть функции, которые недопустимы в JSON.

0 голосов
/ 13 мая 2011

Вы можете попытаться проверить ваш объект по JSON-схеме

Но это может быть излишним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...