JavaScript与其他语言的变量缓存

时间:2012-02-28 18:18:00

标签: java javascript caching compiler-construction

最近有人告诉我这很糟糕:

var el = $("#myID");
$(el).addClass("a");
$(el).addClass("b");
$(el).addClass("c");

并且它应该像这样缓存:

var $el = $("#myID");
$el.addClass("a");
$el.addClass("b");
$el.addClass("c");

所以,我的问题是,为什么不自动优化?在Java和其他语言中,我认为编译器足够聪明,可以自己进行缓存。

即,这:

// myList is a List<String>
String str = myList.get(0);
String trimmed = str.trim();
String sub = str.substring(0, 5);
boolean abc = str.startsWith("abc");

不比这更有效:

String trimmed = myList.get(0).trim();
String sub = myList.get(0).substring(0, 5);
boolean abc = myList.get(0).startsWith("abc");

任何了解编译器的人都可以在这里给我一些见解吗? JavaScript只是那样愚蠢吗?或者Java /其他人也是如此?

2 个答案:

答案 0 :(得分:4)

$(el)是一个相对昂贵的函数调用。编译器无法知道它将始终为每个调用返回相同(或至少是等效的)对象,因此它无法进行您建议的优化。

这不一定是语言的功能。我确信会有语言(也许你可以将函数声明为幂等),编译器可以在其中推断返回值并进行优化。

我非常确定Java编译器/优化器可以在相对简单的情况下执行此操作。

因此,对于那些相同的简单情况,没有理由为什么Javascript编译器在适当的情况下不应该这样做。但值得考虑的是编译是在浏览器中进行的,因此可能会限制您希望进行优化的CPU时间,以免影响用户的浏览体验。

答案 1 :(得分:1)

您认为编译器比实际更聪明!

请记住,编译器只知道语言的语法和语义,而不是API的契约。因此,即使您可能知道$(el)将始终是同一个对象,但所有编译器都知道“使用参数$调用el函数”,它不能假设给定相同参数的函数将返回相同的值。 (例如,考虑Math.random()函数。)同样,从您的Java示例中,我们可能知道myList.get(0)将始终是同一个对象(通常,除非发生其他事情,对吧?)但是编译器不能。

所以,是的,存储对从函数调用中检索的对象的引用并对该引用进行操作确实更有效,而不是重复进行函数调用。