我不确定这只是一个错误还是一个预期的功能。
基本上,我有这个微小的功能(我现在看到end
在这里是蓝色的,但这很好用,如果我将它重命名为其他东西我还有问题):
function f(a, b) {
var start = Math.min(a, b);
var end = Math.max(a, b);
tb.selectionStart = start;
tb.selectionEnd = end;
};
当关闭编译时,我得到:
function f(a,b){var c=Math.max(a,b);tb.selectionStart=Math.min(a,b);tb.selectionEnd=c};
但是,为什么selectionStart
直接设置为Math.min
,而selecitonEnd
设置为变量(c
),首先声明? tb.selectionEnd=Math.max(a,b)
不是更短吗?
任何想法都表示赞赏。
答案 0 :(得分:4)
编辑:此链接中有“官方”答案: https://web.archive.org/web/20151226143155/http://code.google.com/p/closure-compiler/issues/detail?id=410 强>
我认为可以内联对变量的赋值,紧接着使用该变量。但是,如果中间有任何声明无法证明没有副作用,那么编译器就不会内联它。
在您的情况下,变量“start”的赋值与“start”的使用仅通过赋值语句分离为“end”。但是,这个语句没有副作用,因为Math.max是一个内部函数,编译器知道它是无副作用的。
但是,在您的情况下,通过语句将对变量“end”的赋值与该变量的用法分开,该语句是对属性的“start”赋值。现在,我相信编译器并不认为仅仅分配属性总是没有副作用;这是因为某些属性在分配时实际上会导致不同的行为,或者更改全局状态(例如RegExp)。在某些系统中,属性分配实际上会触发某些特定于系统的功能(例如硬件接口),这些功能可能会反过来包含副作用。
这就是为什么有时你会得到这样的代码:
foo.bar = 1;
foo.bar = 2;
foo.bar = 3;
编译器不会消除前两个语句,因为赋值给“bar”可能会产生副作用。
因此,在您的问题中,变量“end”无法内联,因为语句tb.selectionStart = start;
可能有副作用(可能仅在奇怪的情况下)。
如果你使“tb”成为局部变量,或者编译器完全控制的东西(例如一个简单的对象:var tb = {};
),那么你会发现编译器内联所有的作业很好。
答案 1 :(得分:3)
如果您粘贴此代码,则可以使用。
function f(a, b) {
var start = Math.min(a, b);
tb.selectionStart = start;
var end = Math.max(a, b);
tb.selectionEnd = end;
};
function f(a,b){tb.selectionStart=Math.min(a,b);tb.selectionEnd=Math.max(a,b)};
我这是封闭编译器的错误。