【问题标题】:constructor from json schema来自 json 模式的构造函数
【发布时间】:2013-08-11 22:04:06
【问题描述】:

有没有办法从 JSON 模式构建对象构造函数?我想创建一个与我的应用程序命名空间关联的 json 模式,我可以编辑一次,并更改对象的属性(在运行时之前)。

我知道你可以写一个伪经典的对象构造函数,比如

var Note = function(input){ 
  var title = input
};
var newNote = new Note("test title");

是否可以从 json 创建类似的结构?这样我就可以写了:

var Note = {
  "title":""
};
var newNote = new Note();
newNote.title = "test title"

我明白以上在语法上是错误的,但我想例如:

var notes = {
  "NotesList":[{
    "title":"note1",
    "content":"test content"
  }]
}
var newNote = new Note();
notes.NotesList.add(newNote);
newNote.title = "new title";

这样我就可以将我的所有对象及其所有子对象都建立在从我的 json 模式创建的对象模板中。如果这不可行,您能推荐一个更好的方法吗?

【问题讨论】:

  • 这实际上不是 JSON,更不用说 JSON 模式,它只是 Javascript 代码。因此,例如引号是不必要的。如果您将.add 更改为.push,您的代码将按原样运行
  • 第三个示例的真正目的是从模式文件中读取 json 并从中创建一个类。
  • 为什么不能直接使用解析后的 JSON?没有必要在只有数据或列表的对象后面有类。
  • 我想使用 json 创建一个类,我可以在该类上调用构造函数来创建具有这些默认属性的新实例。
  • 您可以将其视为设计时函数,并使用 t4 模板之类的东西从 JSON 模式作为输入生成伪经典版本(或其他版本)。只是一个想法。

标签: javascript json oop


【解决方案1】:

我不确定我是否完全理解了您的问题。但是,如果您希望将函数转换为 JSON,那么是的,这绝对是可能的。

您需要做的就是使用像 acorn 这样的 JavaScript 解析器,它使用 Mozilla Parser API 以 JSON 格式生成构造函数的 abstract syntax tree。例如:

var ast = acorn.parse(Note);
var json = JSON.stringify(ast, null, 4);
alert(json);

function Note(input) {
    var title = input;
}

查看演示 here。上面的代码产生以下输出:

{
    "type": "Program",
    "start": 0,
    "end": 47,
    "body": [
        {
            "type": "FunctionDeclaration",
            "start": 0,
            "end": 47,
            "id": {
                "type": "Identifier",
                "start": 9,
                "end": 13,
                "name": "Note"
            },
            "params": [
                {
                    "type": "Identifier",
                    "start": 14,
                    "end": 19,
                    "name": "input"
                }
            ],
            "body": {
                "type": "BlockStatement",
                "start": 21,
                "end": 47,
                "body": [
                    {
                        "type": "VariableDeclaration",
                        "start": 27,
                        "end": 44,
                        "declarations": [
                            {
                                "type": "VariableDeclarator",
                                "start": 31,
                                "end": 44,
                                "id": {
                                    "type": "Identifier",
                                    "start": 31,
                                    "end": 36,
                                    "name": "title"
                                },
                                "init": {
                                    "type": "Identifier",
                                    "start": 39,
                                    "end": 44,
                                    "name": "input"
                                }
                            }
                        ],
                        "kind": "var"
                    }
                ]
            }
        }
    ]
}

您可以将上述 AST 保存在 JSON 文件中,并在需要时加载它。您可以使用escodegen 将 AST 转换回 JavaScript,如下所示:

alert(escodegen.generate(ast));

查看演示 here。然后您可以eval 生成的代码并根据需要使用Note 构造函数。

【讨论】:

    【解决方案2】:

    我找到了我所寻找的答案。我的最终目标是创建一个包含子数组的对象,每个子数组都可以有子数组等。然后该对象将用作我整个应用程序的命名空间,例如:

    var myobj = {};
    

    我想使用 JSON 来指定这个对象的属性,然后根据这些属性构建构造函数,例如:

    var myObj = {
    "name": "genericname",
    "id": "uniqueid",
    "children": [
        {
            "grandchildren": [
                {
                    "name": "child",
                    "age": "0"
                }
            ]
        }
    ]
    };
    

    我最终做的是,从这里构建构造函数,然后将它们克隆到我的新对象中,这样它们就可以拥有这些默认值:

    myObj.Child = function(){
      var child = myObj.children[0];
      return child;
      //this is the unmodified constructor child
    };
    var myObj.createChild = function(){
      var newChild = new Clone(myObj.Child());
      //do stuff to this is new child which can be modified without changing the original
      return newChild;
    };
    

    【讨论】:

      猜你喜欢
      • 2015-10-06
      • 2016-10-07
      • 1970-01-01
      • 2014-02-11
      • 2012-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多