闭包编译器更新字符串属性名称引用

Closure Compiler update string property name references

本文关键字:引用 属性 字符串 编译器 更新 闭包      更新时间:2023-09-26

假设我们有一个对象的轮询,带有对象的函数,如下所示,我想使用类似_.invoke的函数来调用每个fn。在通过_.invoke(pool, "fn"进行gcc高级最小化之前,我们可以很容易地做到这一点),没有问题。但是,缩小后的fn可能是c或其他属性名称。。。是否有向gcc提示字符串正在引用属性名?我希望它在缩小代码后将我的invoke调用更新为_.invoke(pool, "c")

对于这个问题的一个可复制的例子,请尝试在这个脚本上运行高级编译的gcc:

// ==ClosureCompiler==
// @externs_url http://cdn.jsdelivr.net/g/underscorejs
// @compilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==
var pool = [{fn: function() {}, prop2: 1}, {fn: function() {}, prop2: 2}, {fn: function() {}, prop2: 3}]
_.invoke(pool, "fn");

它产生明显不等价的代码:

_.invoke([{a:function(){},b:1},{a:function(){},b:2},{a:function(){},b:3}],"fn");

我希望最终编译的代码将是

_.invoke([{a:function(){},b:1},{a:function(){},b:2},{a:function(){},b:3}],"a");

有几种方法:

1) 引用原始属性定义:

{"fn": ...}

2) 在外部文件中提供定义:

/** @type {Object} */
var methods;
methods.fn;

3) 使用神奇的"JSCompiler_renameProperty"方法:

_.invoke(pool, JSCompiler_renameProperty("fn"));

这种方法使用不多(因此有更高的机会变得脆弱),也不建议使用基于类型的优化。请注意,您有一个提供存根的实现,如:

function JSCompiler_renameProperty(a) { return a; }

如果您希望代码在未编译或编译时不发出警告。

只需引用您不希望gcc重命名的属性名称:

var pool = [{"fn": function() {}, "prop2": 1}, {"fn": fun ...

另请参阅:不一致的属性名称