- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用Google Closure Compiler (ADVANCED_OPTIMIZATIONS),似乎当代码封装在一个函数中时,有一些高级优化是做不到的。
(function(){
var db = {};
/** @enum {number} */
db.col = { One: 0, Two: 3, Three: 4, Four: 1, Five: 2, Six: 7, Seven: 8 };
alert(db.col.Two); alert(db.col.Three); alert(db.col.Four);
})();
var db = {};
/** @enum {number} */
db.col = { One: 0, Two: 3, Three: 4, Four: 1, Five: 2, Six: 7, Seven: 8 };
alert(db.col.Two); alert(db.col.Three); alert(db.col.Four);
编译为
var a={a:{f:0,d:3,c:4,b:1,e:2,h:7,g:8}};alert(a.a.d);alert(a.a.c);alert(a.a.b);
alert(3);alert(4);alert(1);
函数封装阻止高级变量替换的原因是什么?有什么方法可以让两个代码片段编译成相同的输出吗?
最佳答案
一种可能的解释:
您所指的 Closure 编译器的功能是“ namespace 扁平化”,这是编译器试图规避与长链 namespace 中的查找相关的成本。
例如,foo.bar.baz.hello.doSomething();
需要导航四个对象的链才能找到 doSomething
属性。通过命名空间扁平化,属性被扁平化为 a
,调用被替换为 a();
—— 一个显着的改进。
因此,在您的第二种情况下,真正有问题的并不是对象 db
。我相信会发生以下优化链:
var db = {};
db.col = { One: 0, Two: 3, Three: 4, Four: 1, Five: 2, Six: 7, Seven: 8 };
alert(db.col.Two); alert(db.col.Three); alert(db.col.Four);
命名空间的扁平化:
var a=0, b=3, c=4, d=1, e=2, f=7, g=8;
alert(b); alert(c); alert(d);
那么,由于 b,c,d 都只使用了一次,所以它们是内联的:
var a=0, e=2, f=7, g=8;
alert(3);alert(4);alert(1);
最后,丢弃未使用的变量 a,e,f,g。
然而,尽管这在全局范围内工作得很好,但当对象在闭包内定义时编译器必须格外小心,因为闭包内可能有函数调用捕获在闭包内定义的对象。闭包内的一切都必须是“无副作用”的,以便编译器“扁平化”对象并消除对象;否则,如果内部函数调用引用的捕获对象不再存在,代码将中断。
alert()
不被认为是无副作用的。因此,假设 db
和 db.col
可能会因调用 alert
而被修改。之后的任何可能不是无副作用的代码都可以引用修改后的 db
或 db.col
,因此不得删除这些对象。 注意:如果 alert()
调用是非无副作用的最后一次调用,则这不适用。
要启用 namespace 扁平化,您必须将对象移出闭包并在无法捕获的全局范围内定义它们:
这会起作用:
var db = {}; // Put the namespace outside, making it global
db.col = {}; // Put sub-namespaces outside also
(function(){
db.col.One = 0; // Avoid using object notation
db.col.Two = 3;
db.col.Three = 4;
db.col.Four = 1;
db.col.Five = 2;
db.col.Siz = 7;
db.col.Seven = 8;
alert(db.col.Two); alert(db.col.Three); alert(db.col.Four);
})();
一个好的实验是:
(function() {
var db = {};
db.col = { One: 0, Two: 3, Three: 4, Four: 1, Five: 2, Six: 7, Seven: 8 };
alert(db.col.Two); // Only one call
var test = db.col.Three + db.col.Four; // This statement is side-effect-free
})();
你瞧!它有效:
alert(3);
但是:
(function() {
var db = {};
db.col = { One: 0, Two: 3, Three: 4, Four: 1, Five: 2, Six: 7, Seven: 8 };
alert(db.col.Two); // First call, anything afterwards is suspect
alert(db.col.Three); // Oops! Cannot eliminate db or db.col!
})();
不有效:
var a={a:{f:0,c:3,b:4,e:1,d:2,h:7,g:8}};alert(a.a.c);alert(a.a.b);
关于javascript - Closure Compiler ADVANCED_OPTIMIZATIONS 和函数封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6285567/
我刚刚开始使用 Google Closure 做一些工作,我想将选择字段的创建移动到它自己的模板中,并使用类似以下内容调用该模板: {call templates.utils.select} {p
我有一些代码,简化后看起来像: fn foo() -> Vec { unsafe { unsafe_iterator().map(|n| wrap_element(n)).co
我正在从脚本内部调用Closure Compiler(closurecompiler.jar)。该脚本还生成Closure Compiler需要编译的一些javascript。有没有办法将此JavaS
以下示例代码生成有关高级优化的编译器警告:“JSC_UNSAFE_NAMESPACE:为命名空间 NS 创建的别名不完整”。如果我删除@enum 注释,它不会发出警告。 var NS = {}; /*
看代码: let add_one = |&: x| { 1 + x }; 我知道x是闭包参数,但是闭包中的&:是什么意思? 最佳答案 这是 Rust 的一个文档不足的部分(并且过时,请参阅评论)。我知
PHP manual for anonymous functions (即闭包)指出: Anonymous functions are currently implemented using the
我从脚本内部调用 Closure Compiler (closurecompiler.jar)。该脚本还生成了一些 Closure Compiler 需要编译的 javascript。有没有办法将这个
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 7年前关闭。 Improve t
当鼠标在文档正文中移动时,我试图调用一个函数。但是,下面的事件处理程序不起作用。 goog.events.listen(document, 'onmousemove', function(e)
我试过了 java -jar compiler.jar --js jj.js --js_output_file jj.js 输出文件大小为 0。 如果我不想从 .min.js 重命名为 .js,我该怎
Google Closure UI库如何与Google DART一起使用? 最佳答案 Dart没有使用JavaScript库的功能。这是设计使然,因为Dart旨在同时针对Dart VM和转换为JS的D
是否可以使用 Google Closure 编译器在两个文件中定义一个类?例如,如果我自动生成一个类并希望为用户输入的代码保留另一个类: 在 MyClass.AutoGenerated.js 中 go
当我在 http://closure-compiler.appspot.com 处的闭包编译器中测试以下代码时: // ==ClosureCompiler== // @output_file_name
是否可以使用 Google Closure 编译器在两个文件中定义一个类?例如,如果我自动生成一个类并希望为用户输入的代码保留另一个类: 在 MyClass.AutoGenerated.js 中 go
当我运行闭包编译器时,会收到一堆这样的警告: [exec] jquery/3.2.1/dist/jquery.js:733: WARNING - Suspicious code. The resul
假设您正在一个具有多个外部库依赖项的 javascript 项目中工作,并且想要在 ADVANCED_OPTIMIZATIONS 模式下使用 Google Closure Compiler 编译您的源
我正在为 PIXI.js 库准备 externs。我收到以下警告: js/Test.js:188: WARNING - Property position never defined on PIXI.
我最近使用 Google 的 Closure 编译器创建了一个 JavaScript 库:https://github.com/bvaughn/task-runner 我打算让这个库供那些也需要完整闭
我正在尝试自学闭包模板。我做了一个简单的文件 simple.soy: {namespace examples.simple} /** * says hello to the world * @pa
我正在将一个项目从 jQuery 迁移到 Closure。我有一些我想编译的只迁移了一半的代码。未编译的源工作正常。我想知道使用 SIMPLE_OPTIMIZATIONS 编译它的编译命令。 原始基于
我是一名优秀的程序员,十分优秀!