Google Closure引入了错误

时间:2012-10-31 17:35:02

标签: javascript google-closure-compiler google-closure

修改

在@Alex的帮助下学到的教训是,你永远不应该在块范围内放置函数声明。并不是说我打算这样做,但是如果你滑倒了,它可能会导致很大的问题。


我有一个脚本文件似乎是通过Google Closure错误压缩的。当我使用原始代码运行我的应用程序时,一切正常。但是当我尝试用Google Closure压缩它时,会引入一些错误。

我没有使用高级选项;我正在使用基本的默认模式

显然我不能指望任何人调试压缩文件,但是我希望有人可以查看未压缩的代码并让我知道我是否在某种程度上做了一些非常愚蠢的事情会欺骗Closure。

关于缩小代码的一些注释:

关闭内嵌 BEFramework.prototype.hstreamLoadBEFramework.prototype.hstreamEvalJson,似乎完全删除了辅助函数getDeleteValuegetValueToDisplay,{{1}和其他人。

未压缩文件如下。

此代码可以manually be compiled by closure here,它应该重现上述症状。

getDisplayForLabel

2 个答案:

答案 0 :(得分:2)

当你使用闭包编译器时,你放弃了对代码的一些控制。它会做各种技巧,并可能删除未使用的代码。

似乎您的功能未被删除,但已重命名。

例如,您致电getDeleteValue ...

getDeleteValue(subprop, currentValue)

现在......

l(g,r)

由于未导出getDeleteValue,因此Closure将其重命名。

使用Closure编译器需要一些技巧和相当多的文档搜索,直到你熟悉它的工作方式。

答案 1 :(得分:1)

嗯,想到的错误太多了。首先,我不明白您是否需要静态引用或实例化值。您没有使用jsDoc标签或类似的东西。编译器最好只使用相应的jsDoc标签。你的逻辑是非常奇怪和错误的制定。原型交替等都发生在IIFE(立即调用的函数表达式)中。你的功能是静态的吗?他们是施工人员吗?我们是人类还是舞者?

在浏览器触发DOMContentLoaded事件之前执行IIFE。你可以做的最多的是jQuery IIFE等效$(function() {})();,它将它绑定到DOMReady或DOMContentLoaded回调。您正在块内定义内联函数,甚至在ECMA语言中也是如此。

虽然大多数脚本引擎支持块内的函数声明,但它不是ECMAScript的一部分(参见ECMA-262,第13和14节)。更糟糕的实现彼此不一致,并与未来的EcmaScript提议不一致。 ECMAScript仅允许在脚本或函数的根语句列表中使用函数声明。而是使用使用函数表达式初始化的变量来定义块中的函数。

var myFunctionName = function (params) {};

你也缺少一些分号。解释你的JS时自动分叉插入并不是完美无瑕的,所以要养成它的习惯。

依赖隐式插入可能会导致细微的,难以调试的问题。不要这样做。你比那更好。

有几个地方缺少分号特别危险:

// 1.
MyClass.prototype.myMethod = function() {
  return 42;
}  // No semicolon here.

(function() {
  // Some initialization code wrapped in a function to create a scope for locals.
})();


var x = {
  'i': 1,
  'j': 2
}  // No semicolon here.

// 2.  Trying to do one thing on Internet Explorer and another on Firefox.
// I know you'd never write code like this, but throw me a bone.
[normalVersion, ffVersion][isFF]();


var THINGS_TO_EAT = [apples, oysters, sprayOnCheese]  // No semicolon here.

// 3. conditional execution a la bash
-1 == resultOfOperation() || die();

那会发生什么?

JavaScript错误 - 首先使用第二个函数作为参数调用返回函数42,然后“调用”数字42导致错误。 在尝试调用x[ffVersion][isIE]()时,您很可能会在运行时收到“未定义此类属性”错误。 除非resultOfOperation()NaNTHINGS_TO_EAT被分配die()的结果,否则会调用die。 为什么呢?

JavaScript要求语句以分号结尾,除非它认为它可以安全地推断它们的存在。在每个示例中,在语句中使用函数声明或对象或数组文字。结束括号不足以表明声明的结尾。如果下一个标记是中缀或括号操作符,Javascript永远不会结束语句。

这确实让人感到惊讶,所以请确保你的作业以分号结尾。