2011-05-13 41 views
1

测试JavaScript中复杂对象完整性的最佳方法是什么?检查复杂JavaScript对象的完整性

我的对象有一堆不同的变量,有些是可选的,有些是必需的。正确的结构对代码的功能至关重要,但是如果我在定义过程中犯了一个错误,找到导致问题的确切值可能会非常乏味。特别是对于告诉我的错误消息,只有“代码中的Somwehere使用了错误的变量类型!”。

我的对象可以是这个样子,例如:

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

谢谢!

+0

可能会更好[codereview](http://codereview.stackexchange.com/) – Neal 2011-05-13 15:01:38

+0

“最好”真的是一个可回答的问题吗?你认为什么会使一种技术比另一种更好? – Malvolio 2011-05-13 15:01:40

+0

@Neal:codereview.se以何种方式适合此? OP目前没有任何他们试图改进的代码。 – 2011-05-13 15:05:39

回答

0

好的,我已经解决了这个问题:我创建了一个对象来定义我的复杂对象应该是什么样子。一种蓝图。

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

然后我运行比较蓝图(“结构”)与对象要测试的功能(“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

你是如何得到这个的?最重要的是:你如何防止任何人通过'javascript:'url注入或控制台覆盖你的函数,所以它总是返回true? – Philzen 2014-03-21 00:44:54

-1

你可以尝试验证自己的对象针对JSON Schema

但是,这可能是矫枉过正。

+0

JSON不能包含函数,这不足以满足OP的对象。 – 2011-05-13 15:03:14

+0

@Matt当你需要解析它时,出于安全原因。但由于它已经被解析,所以对象是绝对不是一种JSON – Mic 2011-05-13 15:05:01

+1

! JSON是JavaScript中对象文字符号的**严格子集**。 – 2011-05-13 15:06:48

4

除了编写一个接收对象作为输入的函数并验证它具有“正确”结构之外,没有一种好方法可以做到这一点。

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 */); 
-1

您可能会尝试JSON Schema Validation。您可能需要进行一些修改,以说明您可以拥有的功能以及在JSON中无效的功能。