Recently I've read this performance guide Let's make the web faster and was puzzled by "Avoiding pitfalls with closures" recommendations (as if these advices were given for CommonLisp users where variable scoping is dynamic):
var a = 'a'; function createFunctionWithClosure() { var b = 'b'; return function () { var c = 'c'; a; b; c; }; } var f = createFunctionWithClosure(); f();
when
f
is invoked, referencinga
is slower than referencingb
, which is slower than referencingc
.
It's quite evident that referencing local variable c is faster than b, but if the iterpreter is written properly (without dynamic scoping - something like chained hashtable lookup..) the speed difference should be only marginal. Or not?
You're right. Modern JS engines will optimize the
scope chain lookup
and theprototype chain lookup
like a lot. Means, AFAIK the engine trys to hold some sort of hash-table with access nodes underneath.This only works if there is no
eval()
(explicity or implicitly, e.g.setTimeout
) or atry-catch
clause ora with statement
invoked. Because of such constructs, the interpretator can't be sure about how to access data and it needs to "fallback" into a classicalscope chain lookup
which really means, it has to crawl through all parent contextvariable / activation objects
and try to resolve the searched variable name. This process of, of course, will take more time for objects/names which are located "far away" from where the lookup processed was started. That in turn means, that accessing data on theglobal object
will always be the slowest.In your snippet, the lookup process for
a
would go likeThe described lookup procedure is for ECMAscript Edition 262 3rd edition. ECMAscript edition 5 has some fundamental changes there.