从模板创建Javascript对象

Dre*_*ene 7 javascript templates json function object

我想从模板创建一个javascript对象.问题是我不知道模板事先会是什么样子.举个简单的例子,如果我有模板功能

template = function (data) {
    return {
        title: data.title
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以跑去template({ title: "Steve" })取回物体

{ title: "Steve" }
Run Code Online (Sandbox Code Playgroud)

因为data.title直到我调用模板函数才进行评估.但是我正在构建一个基于用户输入的对象,其中字段名称事先是未知的,并且可以深深嵌套在对象中的任何位置.

如果我定义了事先返回的对象,那么data.title示例中的字段已经被评估,并且不会使用输入数据.例如,我希望能够像模板一样定义模板对象

obj = { title: this.title }
Run Code Online (Sandbox Code Playgroud)

然后将模板重新定义为

template = function () {
    return obj
}
Run Code Online (Sandbox Code Playgroud)

并打电话template.call({title:"Steve"}).但目前我回来了

{ title: undefined }
Run Code Online (Sandbox Code Playgroud)

因为this.title我定义时已经评估过了obj.也许我正在以错误的方式接近这个,因为我不断得出结论,我必须通过字符串化修改函数,修改字符串以包含未评估的代码this.title并从字符串创建新函数.但这似乎是一个非常可怕的想法.

遍历对象寻找要替换的特殊值似乎既昂贵又复杂.我也找了一些javascript对象模板库,但没有找到任何东西.

编辑:为了更清楚地表明输入数据和模板结构不一定匹配,我可能想要一个看起来像的模板

template = function (data) {
    return {
        name: "Alfred",
        stats: {
            age: 32,
            position: {
                level: 10,
                title: data.title
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并致电template({title:"Manager"})得到

{ "名": "阿尔弗雷德", "统计":{ "时代":32, "位置":{ "级":10, "称号": "经理人"}}}

Dre*_*ene 8

所以我设法通过(ab)使用函数作为元数据来标记应该在模板中替换的值来解决这个问题.这可以通过两件事来实现:

  1. 我只需要有效的JSON值,所以我可以肯定地说函数不是文字用户输入
  2. JSON.stringify有一个replacer参数,它将遍历该对象,并可用于将输入数据传递给模板

使用像这样的模板生成器

var templateMaker = function (object) {
    return function (context) {
        var replacer = function (key, val) {
            if (typeof val === 'function') {
                return context[val()]
            }
            return val;
        }
        return JSON.parse(JSON.stringify(obj, replacer))
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个模板对象,用返回字段名称的函数替换字段名称

var obj = {
    name: "Alfred",
    stats: {
        age: 32,
        position: {
            title: function () { return 'title' },
            level: function () { return 'level' }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我创建模板函数,定义我的输入,并将其渲染到一个对象

var template = templateMaker(obj);

var data = {
    title: "Manager",
    level: 10
}

var rendered = template(data);
Run Code Online (Sandbox Code Playgroud)

而且神奇地说,对象输出看起来像

{ "name": "Alfred", "stats": { "age": 32, "position": { "title": "Manager", "level": 10 } } }