奇怪的闭包编译器问题
我在高级模式下使用 Google 的闭包编译器,但遇到了一个奇怪的问题。以下是未编译的代码,其中包含从运行的编译版本返回的日志语句:
goog.provide('frame.store');
goog.require('frame.storeBack.LocalStore');
goog.require('frame.storeBack.Mem');
frame.store = (function() {
/** prioritised list of backends **/
var backends = [
frame.storeBack.LocalStore,
frame.storeBack.Mem
];
frame.log(backends);
// [function rc(){}, function tc(){this.q={}}]
frame.log(frame.storeBack.LocalStore === backends[0]);
// true
frame.log(frame.storeBack.LocalStore.isAvailable === backends[0].isAvailable);
// false
frame.log(frame.storeBack.LocalStore.isAvailable);
// function sc(){try{return"localStorage"in window&&window.localStorage!==k}catch(a){return l}}
frame.log(backends[0].isAvailable);
// undefined
for (var i=0, len=backends.length; i<len; i++)
if (backends[i].isAvailable())
return new backends[i]();
// Uncaught TypeError: Object function rc(){} has no method 'Ga'
throw('no suitable storage backend');
})();
由于某种原因,当通过后端数组访问 LocalStore 时,静态方法 isAvailable 不存在,而当通过全局命名空间访问 LocalStore 时,静态方法 isAvailable 不存在。
谁能明白为什么吗?
编辑:供参考,这里是方法声明:
frame.storeBack.LocalStore.isAvailable = function() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
}catch (e) {
return false;
}
};
I'm using Google's Closure Compiler in advanced mode, and I'm having a strange issue. Here is the uncompiled code, with returned log statement from the compiled version running:
goog.provide('frame.store');
goog.require('frame.storeBack.LocalStore');
goog.require('frame.storeBack.Mem');
frame.store = (function() {
/** prioritised list of backends **/
var backends = [
frame.storeBack.LocalStore,
frame.storeBack.Mem
];
frame.log(backends);
// [function rc(){}, function tc(){this.q={}}]
frame.log(frame.storeBack.LocalStore === backends[0]);
// true
frame.log(frame.storeBack.LocalStore.isAvailable === backends[0].isAvailable);
// false
frame.log(frame.storeBack.LocalStore.isAvailable);
// function sc(){try{return"localStorage"in window&&window.localStorage!==k}catch(a){return l}}
frame.log(backends[0].isAvailable);
// undefined
for (var i=0, len=backends.length; i<len; i++)
if (backends[i].isAvailable())
return new backends[i]();
// Uncaught TypeError: Object function rc(){} has no method 'Ga'
throw('no suitable storage backend');
})();
For some reason the static method isAvailable is not present when LocalStore is accessed via the backends array, and is present when it's accessed via it's global namespace.
Can anyone see why?
EDIT: for reference, here is the method declaration:
frame.storeBack.LocalStore.isAvailable = function() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
}catch (e) {
return false;
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
打开
--debug true
来检查输出以及frame.storeBack.LocalStore.isAvailable
的重命名内容。转储变量名称映射以检查frame.storeBack.LocalStore.isAvailable是否已展平。
例如,闭包编译器可能首先将
frame.storeBack.LocalStore.isAvailable
展平为frame$storeBack$LocalStore$isAvailable
,然后重命名整个到全局函数“a”或其他东西。这称为命名空间扁平化。检查调试输出以查看您的函数声明是否已重命名为:在这种情况下,直接调用
frame.storeBack.LocalStore.isAvailable()
仍将调用扁平化的全局版本,这里没有问题!但是,您不能再认为isAvailable()
存在于frame.storeBack.LocalStore
(另一个对象)中。在编译的输出中,frame.storeBack.LocalStore.isAvailable
和frame.storeBack.LocalStore
现在是分开的。这是编译器命名空间扁平化的行为(如果发生的话)。您在将属性放入构造函数本身时遇到了麻烦 - 编译器对您可能意想不到的类进行了大量优化。
检查调试输出和变量名称映射进行确认。您可能必须删除闭包包装函数才能查看映射文件中的实际名称。
Turn on
--debug true
to check your output and whatframe.storeBack.LocalStore.isAvailable
is renamed to.Dump a variables name map to check whether
frame.storeBack.LocalStore.isAvailable
has been flattened.For example, the Closure Compiler may flatten
frame.storeBack.LocalStore.isAvailable
first toframe$storeBack$LocalStore$isAvailable
, then rename the whole thing to the global function "a" or something. This is called flattening of namespaces. Check the debug output to see whether your function declaration has been renamed to:In such case, calling
frame.storeBack.LocalStore.isAvailable()
directly will still call the flattened global version, no prob here! However, you can't expact thatisAvailable()
exists inframe.storeBack.LocalStore
(another object) any more. In the compiled output,frame.storeBack.LocalStore.isAvailable
andframe.storeBack.LocalStore
are now separated. This is the behavior of the compiler's namespace flattening, if it happens.You're asking for trouble putting properties into a constructor function itself -- the compiler does a lot of optimizations on classes that you may not expect.
Check the debug output and variable names map to confirm. You may have to remove the closure wrapper function in order to see the actual names in the map file.
不确定你的后端到底是什么......
但你不应该实例化它们吗?
Not sure what your back ends are exactly...
But shouldn't you instantiate them?