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?
Objects created using object literal are singletons, this means when a change is made to the object, it affects the object entire the script. Whereas if an object is created using constructor function and a change is made to it, that change won't affect the object throughout the script.
Objects created using object literals are singletons. This means when a change is made to the object, it affects that object across the entire script. Object defined with a function constructor let us have multiple instances of that object. This means change made to one instance, will not affect other instances.
Object literal enhancement allows us to pull global variables into objects and reduces typing by making the function keyword unnecessary.
The Object literal notation is basically an array of key:value pairs, with a colon separating the keys and values, and a comma after every key:value pair, except for the last, just like a regular array. Values created with anonymous functions are methods of your object. Simple values are properties.
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:
arguments
(the array-like thing you can use to access arguments)var
in the execution context; their values are initially undefined
(regardless of whether the var
has an initializer on it).var
statements that have initializers (e.g., var a = 2;
) are treated exactly like assignment statements (a = 2;
); the var
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With