0

I'm having a bit of confusion over which (if any) of these javascript initializes to use, as from what I can tel, they all do the same thing. Are there cases in which I should use one or he other? Mt project requires me to encapsulate several functions and namespaces in a single object so that we don't clutter te global scope with variable names, put I'm especially unclear as to the difference between +function(){}(); and (function())();

Any help would be greatly appreciated. Keep in mind the end goal is for all of our function to be encapsulated in a single namespace. IE MyCompany.function, MyCompany.Namepsace.Function ...

<script>
    var Ford = {};
    +function() {
        Ford.start = function() {
            console.log("Ford just started");
        };
    }();
    Ford.start();
</script>

<script>
    var Honda = {};
    (function() {
        Honda.start = function() {
            console.log("Honda just srtarted");
        };
    })();
    Honda.start();
</script>

<script>
    var Toyota = function() {
        return {
            start: function() {
                console.log("Toyota just strted");
            }
        };
    }
    var car = new Toyota();
    car.start();
</script>
4
  • 2
    The first two are the same, but the self invocing function is'nt really needed, it could just as well have been a regular object literal, the third is more of a class that returns an object, hence the new keyword. Commented Feb 6, 2013 at 22:32
  • @adeneo -- actually the object created with new is getting discarded due to the return. It's functionally similar to the first two except that it creates a new object literal instead of using an existing one Commented Feb 6, 2013 at 22:34
  • Yes, the third is a class-like function that returns a new instance of the object which is then stored in the variable which is then used to initialize the start() funtion. The question actually states that they all do the same thing, so that much is implied? The difference between the + and the ( on the self invocing function is "nothing" as the returned result is irrelevant. Commented Feb 6, 2013 at 22:40
  • look at the prototype re: speed vs returning properties...see some discussion here: ejohn.org/blog/simple-class-instantiation Commented Feb 6, 2013 at 22:43

2 Answers 2

2

Javascript functions are only invoked as constructors when the new keyword is used. new creates a new object instance, inherits from the constructor's prototype, and makes the context of the this keyword the newly created object instance. So if you're not using the prototype to inherit properties or the keyword this to create new properties in the constructor--you don't really need to use a constructor.

I think what you're looking for is the module pattern which is implemented using immediately invoked functions. Both of your first two examples use immediately invoked functions. I believe the style (function(){}()); is preferred to +function(){}();. Both the surrounding () and the + cause the javascript parser to expect a function expression rather than a function declaration and this allows the trailing () to invoke the function. Besides being somewhat less readable + may also alter the return value of the function.

I think you want some variation on this (copied from link):

var MODULE = (function () {   
    var module = {};
    var privateVariable = 1;

    function privateMethod() {
        // ...
    }

    module.moduleProperty = 1;
    module.moduleMethod = function () {
        // ...
    };

    return module;
}());
Sign up to request clarification or add additional context in comments.

1 Comment

Good answer and good link. When I first started to really learn how JavaScript works, I found the new operator to be way too confusing. I decided at the time that I would avoid it whenever possible. Thanks for giving a nice description of what it really does (although I will still try to avoid using it).
1

While all of that is valid JS, you're making assumptions that lead me to believe you may not understand how JS works. The first two example are not constructors in the usual sense at all...they're sort of module pattern, but not even. you could condense it to

var Honda = {}; 
Honda.start = function() { console.log("Honda just started"); }

and forget the self-executing function. What is shown above is similar to what you'd think of as a static function in other languages:

public class Honda {
    public static void start() { Console.WriteLine("Honda Just Started"); }
}

If you wanted an instance function, you need to either attach to the prototype, or to the this keyword in the constructor:

Prototype:

var Honda = function() {}
Honda.prototype.start = function() { console.log("Honda just started"); }

This:

var Honda = function() {
    this.start = function(){
        console.log("Honda just started");
    }
}

Your final example, with Toyota indicates you have a fundamental misunderstanding of how function constructors work. Your object has been discarded, and in return you get some object literal which could have been written:

var Toyota = {
    start: function(){
        console.log("Toyota just started");
    }
}

What you (probably) intend is the "this" pattern I explained on the Honda example above:

var Toyota = function() {
    this.start = function() {
        console.log("Toyota just started");
    }
}

Finally, when writing "namespaced" libraries of functions, the module pattern may be your best friend. This lets you maintain private state without the need for a formal constructor/prototypes, etc:

var MyCompany = {};

//car module
(function(ns){
    var module,
        _isStarted;

    function start() { console.log('start'); _isStarted = true; }
    function stop() { console.log('stop'); _isStarted = false; }
    function isStarted() { return _isStarted; }

    module = {
        start: start,
        stop: stop,
        isStarted: isStarted
    }

    ns.CarModule = module;
}(MyCompany));

//use:
MyCompany.CarModule.start();
if(MyCompany.CarModule.isStarted()) { MyCompany.CarModule.stop(); }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.