1

我在尝试重命名我的 JSON 属性时遇到了闭包编译器的高级优化问题。我正在使用丰富的自动完成控件,并使用从我的操作返回的 JSON 来提供它,其中包含具有姓名和电话属性的联系人。Closure 编译器在我的方法和模板中重命名 Name 和 Phone。在该方法中,我可以通过使用属性名称作为对象的字符串键来绕过它,但我不知道如何使用模板来做到这一点:

/**
 * @param {{Name: string, Phone: string}} item Item returned for autocomplete
 */
example.makeRow = function (item) {
    item.render = function (node, token) {
        // item.Phone + '</div>' + '<div style="float: right">' + item.Name;
        node.innerHTML = template.autocomplete(item); 
    }
}

我的 JSON 对象具有属性“Name”和“Phone”的全名,但该函数将它们重写为“Hx”和“Az”之类的东西。我的模板同上:

{namespace template}

/**
 * Single row in the example autocomplete box.
 * @param Phone Contact's phone number
 * @param Name Contact's full name
 */
{template .autocomplete}
{$Phone}<span style="padding-left: 15px">{$Name}
{/template}

如果我将这两行添加到 makeRow 函数的开头,它会将压缩名称设置为原始名称中的正确值:

item.Name = item['Name'];
item.Phone = item['Phone'];

这样做在空间和性能方面似乎都很浪费。此外,我无意为我的所有 JSON 对象执行此操作,我计划将来在我的应用程序中使用很多(这只是一个简单的测试)。我不知道如何将新名称映射到旧名称。我可以创建一个源图,但是只有一堆数字,我不知道它们是什么意思。如果我能弄清楚,那么也许我可以在 C# 中编写一个简单的属性映射器来创建具有缩短名称的动态对象。

如果我必须使用简单的优化模式,考虑到闭包库中所有对象和属性的冗长名称,这将很难。它应该很简单。我认为如果他们有一个 @json 标签而不是 @param 会阻止重命名,或者有一些其他信号让 @param 不重命名对象的属性,那就太好了:

 * @param {{Name: string, Phone: string}} item Item returned for autocomplete

会成为

 * @json {{Name: string, Phone: string}} item Item returned for autocomplete

我发现我可以通过创建一个 externs.js 文件并在编译时指定它来使属性名称保持不变:

var foo = {};
foo.Name = null;
foo.Phone = null;

我认为任何具有这些名称的对象属性都不会被压缩,是这样吗?我想我可以写一些助手来生成我将使用的类的长属性名称列表。此外,我可能喜欢在某些事情上使用动态类型,并且担心我可能会忘记或拼错属性名称。


编辑:

不是项目想要支持的东西,他们建议将对象作为参数,如下所示:

{namespace template}

/**
 * Single row in the example autocomplete box.
 * @param json Object with actual values
 */
{template .autocomplete}
{$json['Phone']}<span style="padding-left: 15px">{$json['Name']}
{/template}
4

1 回答 1

1

Closure 支持的最接近的东西是 extern。只需为您的 JSON 对象创建一个 extern,将其传递给编译器,一切都会如您所愿。这是您的案例的基本示例:

/** @constructor */
function AutoCompleteItem() {}

/** @type {string} */
AutoCompleteItem.prototype.Name;

/** @type {string} */
AutoCompleteItem.prototype.Phone;

请注意,仅使用括号语法 ( object['Name']) 访问 JSON 属性是很常见且完全可以接受的——这将编译到object.Name最终输出中,并且避免必须创建 extern。

于 2011-07-04T00:04:40.137 回答