Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我是否可以告诉闭包编译器停止重命名属性(仅针对特定类型)?_Javascript_Google Closure Compiler - Fatal编程技术网

Javascript 我是否可以告诉闭包编译器停止重命名属性(仅针对特定类型)?

Javascript 我是否可以告诉闭包编译器停止重命名属性(仅针对特定类型)?,javascript,google-closure-compiler,Javascript,Google Closure Compiler,这个问题如下:约翰对这个问题的回答引出了第二个问题 如果我按照建议声明外部类型: /** @interface */ function SpanishNoun() {} /** @type {string} */ SpanishNoun.prototype.english; /** @type {string} */ SpanishNoun.prototype.spanish; 然后像: /** * @param {SpanishNoun} n */ exp.foo = function

这个问题如下:约翰对这个问题的回答引出了第二个问题

如果我按照建议声明外部类型:

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

/**
 * @param {SpanishNoun} n 
 */
exp.foo = function (n) {
    console.log(n.english, n.spanish, n['english'], n['spanish']);  
}
将根据需要编译为:

function(a){console.log(a.english,a.spanish,a.english,a.spanish)};
属性不会像往常一样重命名。如果没有extern声明,编译后的代码如下所示:

function(a){console.log(a.a,a.c,a.english,a.spanish)
那很好。问题是编译器已经停止在所有地方重命名“english”和“spanish”。即使它们不是外部类型

/**
 * @param {AnotherType}  
 */
exp.bar = function (c) {
    c.other = c.english;
}
编译成

function(a){a.b=a.english};
有没有办法阻止这一切?如果没有,这种行为有什么原因吗


我想使用extern类型来处理源于服务器且没有重命名属性的JSON对象。但是,如果每次我声明一个extern时,我都在消耗编译器重命名和收缩代码的能力,那么我会找到另一种方法。也许我会使用编译器生成的属性重命名映射(
--property\u map\u output\u file
),并在服务器上生成JSON响应时使用它。

闭包编译器可以根据类型重命名:
这也增强了其他优化,如内联和死代码删除。这是Google内部使用的,但会带来成本,因为如果您在类型声明中“撒谎”,它会引入一些难以调试的场景。

这是闭包的标准行为,以避免出现错误(您可以阅读闭包网站,了解为什么这是必要的)。闭包总是将相同的属性名称重命名为相同的损坏名称。另一方面,它不会重命名同名的所有属性(无论在何处),因为本质上不重命名只是重命名为自身。有一个标志(称为
ambiguateProperties
或类似的标志)可以打开,以避免出现这种情况,但它只是实验性的。这种标准行为的原因是,您可以编写一个只接受对象的函数,并对该对象使用
english
属性。闭包无法知道您传递的是什么对象,以及该对象的
english
属性是否已重命名。由于JavaScript是一种非类型化语言,您可以执行此类操作(通过传入不同类的不同对象),因此编译器必须将相同的属性名称重命名为相同的字符串,以避免无法确定映射到哪个版本的名称。该链接不再起作用。也许这是一个新的(不再是实验性的)链接: