Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Object Literal notation vs plain functions and performance implications?

Tags:

javascript

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?

like image 857
ace Avatar asked Apr 22 '11 10:04

ace


People also ask

What is the difference between an object and an object literal?

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.

What is the difference between object literal and object constructor in JavaScript?

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.

What is the purpose of object literal enhancement?

Object literal enhancement allows us to pull global variables into objects and reduces typing by making the function keyword unnecessary.

What is literal notation in JavaScript?

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.


1 Answers

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:

  1. A behind-the-scenes execution context object is created.
  2. A behind-the-scenes variable object for that execution context is created.
  3. In the case of a function context:
    1. A property is added to the variable object for arguments (the array-like thing you can use to access arguments)
    2. A property is added to the variable object for each of the function's named arguments, with the value of the argument
    3. 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.
  4. Properties are created on the variable object for each variable declared with var in the execution context; their values are initially undefined (regardless of whether the var has an initializer on it).
  5. 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.
  6. 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;); 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.

like image 67
T.J. Crowder Avatar answered Sep 21 '22 08:09

T.J. Crowder