Search code examples
javascriptmethodsdrymodule-pattern

JS: what's the difference between function vs method on function expressions?


Lately I've been learning JS module pattern and I've seen at least 3-4 ways to create function expressions with public and private properties. My problem is I don't understand what's the best difference between them and what's the best approach / best practice.

The syntax on the 4 examples below are different but all of are invoked the same way. Can you explain me what's the difference between them?

Example A - I declare function func() and return only the method/function name.

var funcA = function() {
    var hi = "hello";

    function bye() {
        return 'bye';
    }

    function hello() {
        return hi;
    }

    return {
        hello: hello
    }
}();

Example B - here I declare foo = function() and return only the method/function name.

var funcB = function() {
    var hi = "hello";

    var bye = function() {
        return 'bye';
    }

    var hello = function() {
        return hi;
    }

    return {
        hello: hello
    }
}();

Example C - here I declare foo = function() inside the return

var funcC = function() {
    var hi = "hello";

    var bye = function() {
        return 'bye';
    }

    return {
        hello: function() {
            return hi;
        }
    }
}();

Example D - same as prev but all the function is wrapped in ().

var funcD = (function() {
    var hi = "hello";

    var bye = function() {
        return 'bye';
    }

    return {
        hello: function() {
            return hi;
        }
    }
})();

In each case if I want to call hello() I just write funcX.hello() and all of them return "hello"

But all of them are created by different ways. What's the correct one? If there is a correct way.

Thanks.


Solution

  • It's worth noting first, that leaving out the var keyword from bye and hello will actually make them global.

    Now the difference between:

    var hello = function () {}
    
    return {
      hello: hello
    };
    

    And

    return {
      hello: function () {}
    };
    

    Is none, because you're just passing the function either way. Storing the function in a variable has the advantage where you can use it in another place in scope.

    Now one difference to be aware of is declaring the function.

    var myFunc = function () {}
    

    vs

    function myFunc () {}
    

    The ones with the keyword infront get brought into scope immediately, so they are available before you reach the declaration. With a var, that's not the case. For example

    function a() {
      b();
    }
    
    a();
    
    var b = function () {
      console.log('hi')
    }
    

    When a is invoked, it will throw an error because b is not defined. If you do it like this though:

    function a() {
      b();
    }
    
    a();
    
    function b() {
      console.log('hi')
    }
    

    It will work fine. This is known as hoisting. The first is called a function expression var thing = function() {} where the last is called a function declaration function thing() {}