[英]Preventing inlining of exported properties as constants w/ Google Closure Compiler
这是输入JavaScript的最小示例(由另一种语言生成,但这既不是这里也不是那里):
goog.provide('foo.bar');
foo.bar.baz = 42;
goog.exportSymbol('foo.bar.baz', foo.bar.baz);
foo.bar.quux = (function quux(){return foo.bar.baz;
});
goog.exportSymbol('foo.bar.quux', foo.bar.quux);
我的期望是,因为foo.bar.baz
未被注释为常量,所以不会将其视为一个常量。 但是,无论如何,高级优化(无论是在本地还是通过编译器服务 )都可以内联:
var d = this;
function f(g, e) {
var b = g.split("."), a = d;
b[0] in a || !a.execScript || a.execScript("var " + b[0]);
for (var c;b.length && (c = b.shift());) {
b.length || void 0 === e ? a = a[c] ? a[c] : a[c] = {} : a[c] = e;
}
}
;f("foo.bar.baz", 42);
f("foo.bar.quux", function() {
return 42;
});
常量内联非常好,但是考虑到已导出的值,因此内联的值并不安全。 我已经尝试使用goog.exportProperty
和@expose
注释来代替goog.exportSymbol
,并且没有运气。
救命? 谢谢!
更新: @expose
现在已弃用。 答案已使用新方法更新。
如您所述, @const
联没有影响。 @const
仅表示该值不变(仅分配/设置一次)。
@nocollapse
是专门为防止属性崩溃而创建的。 鉴于:
goog.provide('foo.bar');
/** @nocollapse */
foo.bar.baz = 42;
alert(foo.bar.baz);
在这种情况下, @nocollapse
的目的是防止编译器将属性折叠为类似以下内容:
var a = 42;
alert(a);
但是,编译器仍从流分析中得知foo.bar.baz
被分配了整数42
并且从未更改。 因此,它将仅使用已知值。
防止内联的唯一可靠方法是导出属性:
goog.provide('foo');
goog.provide('foo.bar');
foo.bar.baz = 42;
goog.exportProperty(foo.bar, 'baz', foo.bar.baz);
alert(foo.bar.baz);
已知(尽管很小)需要向编译器规定重命名是安全的,但内联不是。 请参阅https://code.google.com/p/closure-compiler/issues/detail?id=971
如果您不使用闭包库,则导出将如下所示:
var foo = {};
foo.bar = {};
/** @nocollapse */
foo.bar.baz = 42;
foo.bar['baz'] = foo.bar.baz;
alert(foo.bar.baz);
如果您的目标是确保不内联或重命名foo.bar.baz
,那么您将需要带引号的属性和@nocollapse
。
goog.provide('foo');
goog.provide('foo.bar');
/** @nocollapse */
foo.bar.baz = 42;
goog.exportProperty(foo.bar, 'baz', foo.bar.baz);
alert(foo.bar.baz);
如果您要将此命名空间提供给他人使用,那么最好的情况是@nocollapse
的组合,以防止崩溃并允许外部更新和goog.exportSymbol
。
goog.provide('foo');
goog.provide('foo.bar');
/** @nocollapse */
foo.bar.baz = 42;
goog.exportSymbol('foo', foo);
goog.exportProperty(foo, 'bar', foo.bar);
goog.exportProperty(foo.bar, 'baz', foo.bar.baz);
alert(foo.bar.baz);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.