Suppose I have functions like:
function foo() {
}
function bar() {
}
I can write above as Object Literal notation:
var Baz = {
foo: function() {
},
bar: function() {
}
};
As far as I understand in the later case, an instance of Baz will be created when the script loads regardless if any Baz function is ever called. In the former case, function object is only created when that function is called. Am I correct about these assumptions?
If I am correct then the former would have higher performance (less memory) than the later in application where these functions are rarely called. But the advantage of开发者_运维问答 the later is that it gives greater modularity and lower global namespace pollution.
What is your take on this from your professional experience? Is there a speed difference?
In the former case, function object is only created when that function is called.
No, the functions are created regardless.
Note that you can also do this:
function foo() {
}
function bar() {
}
var Baz = {
foo: foo,
bar: bar
};
Or this:
var Baz = (function() {
function foo() {
}
function bar() {
}
return {
foo: foo,
bar: bar
};
})();
The primary purpose of putting the functions on Baz
as properties is to make them available as "methods" on Baz
. This might be for convenience, for "namespacing", etc. In your first form (and my first form above), if that code is at global scope, foo
and bar
are added to the global scope, which can get pretty crowded pretty fast (esp. on browsers). In your second example, the only global symbol is Baz
because the functions are anonymous. In my final example above, the only global symbol is Baz
but the functions aren't anonymous, they have names that debuggers and stack traces can show you (which is a good thing; more here).
In terms of trying to optimize when functions get created, here's how it works: When execution enters a given context (the global context, or the context related to calling a function), these things are done:
- A behind-the-scenes execution context object is created.
- A behind-the-scenes variable object for that execution context is created.
- In the case of a function context:
- A property is added to the variable object for
arguments
(the array-like thing you can use to access arguments) - A property is added to the variable object for each of the function's named arguments, with the value of the argument
- If the function has a name, its name is added as a property of the variable object and has the value of the function object.
- A property is added to the variable object for
- Properties are created on the variable object for each variable declared with
var
in the execution context; their values are initiallyundefined
(regardless of whether thevar
has an initializer on it). - Every function declaration in the context is processed. (Function expressions are not processed yet; more on the difference below.) A property on the variable object for each function name is created and receives the function object as its value.
- Step-by-step code execution begins.
- Like all expressions, function expressions are evaluated when they're encountered in the step-by-step flow.
var
statements that have initializers (e.g.,var a = 2;
) are treated exactly like assignment statements (a = 2;
); thevar
aspect of it was done much earlier. (var
is frequently misunderstood. For instance, we had this question just yesterday.)
You'll note the difference above between function declarations and function expressions. You can tell which is which by looking to see whether you're using the result as a right hand value — that is, are you assigning the result to a variable, using it as the right-hand side of a property definition in an object literal, or passing it into a function. If you are, it's a function expression. If you're not, it's a function declaration.
Function declaration example:
function foo() {
}
Function expression example:
var foo = function() {
};
Another:
var Baz = {
foo: function() { }
};
(The foo
line is a property declaration in an object literal that uses a function expression for the value.)
Named function expression example:
var f = function foo() { // <== Don't do this (more below)
};
Named function expressions should be valid, but they're poorly-supported by implementations in the wild (particularly IE) and so for now they must be avoided. More here.
精彩评论