为什么Closure编译器会重命名外部类型的属性?

13

我把这段代码放在一个外部文件中:

/** @typedef {{english: string, spanish: string}} */
var SpanishNoun;

然后我有JavaScript:

/**
 * @param {SpanishNoun} n 
 */
exp1.processData3 = function (n) {
    console.log("pd3:", n.english, n.spanish, n['english'], n['spanish']);
}

编译后的结果是:

function(a){console.log("pd3:",a.a,a.c,a.english,a.spanish)};

那么它仍然将'english'重命名为'a'等。你如何阻止它?为什么它认为可以重命名"extern"的东西。

Rob

后续问题

John的答案引发了另一个问题:我能告诉Closure编译器,仅针对特定类型停止重命名属性吗?

1个回答

5

typedef不参与重命名计算。

这个类型定义将会:

/** @interface */
function SpanishNoun() {}
/** @type {string} */
SpanishNoun.prototype.english;
/** @type {string} */
SpanishNoun.prototype.spanish;

1
我尝试了这个方法,它确实起作用,但不是我预期的方式。它会导致代码中所有名为“english”和“spanish”的属性都不被重命名,即使它们属于不相关的类型。这似乎不太对。有没有办法停止这种情况发生?我可能会将此作为单独的后续问题发布。 - Rob N
2
@Rob N - 这是闭包的标准行为,以避免出现错误(您可以阅读Closure网站以了解为什么这是必要的)。Closure总是将相同的属性名称重命名为相同的混淆名称。另一方面,它不会重命名所有具有相同名称的属性(无论它们在哪里)--因为本质上非重命名就是将其重命名为自己。有一个标志,您可以打开来避免这种情况,但它只是实验性的。 - Stephen Chung
你可以使用基于类型的优化来改变属性重命名的“所有属性”方面:https://code.google.com/p/closure-compiler/wiki/ExperimentalTypeBasedPropertyRenaming但是需要注意,外部定义与使用之间存在类型关系,并且已知于编译器。在这种情况下,通过在Object.prototype上添加一个extern定义可以防止给定名称的属性的所有重命名。 - John
这在当前版本的Closure Compiler中已经发生了变化。属性现在从externs中的记录类型引用中提升。 - John
@John,你能详细解释一下你最后一条评论吗?我试着使用--use_types_for_optimization,但它仍然像Rob遇到的那样排除了所有具有相同名称的属性进行重命名。 - Jim
@RobN 你解决了吗? - Jim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接