Gabriel
Gabriel

Reputation: 2750

How do I call another function in the same javascript namespace?

I like to organize my javascript in namespace style like below. What I want to know : is there another (shorter?) way to call myFirstFunction() from mySecondFunction()? I tried this.myFirstFunction() and it's not working so maybe there's some kind of mysterious trick here that I don't know.

var myNameSpace = {
    myFirstFunction: function(){
        alert("Hello World!");
    },
    mySecondFunction: function(){
        myNameSpace.myFirstFunction();
    }
}

Thanks for your help as usual, people of SO! :)

Upvotes: 10

Views: 7113

Answers (5)

T.Todua
T.Todua

Reputation: 56371

If you are attaching to event:

possible issue could be if you are attaching Namespace's function to event, like:

$(el).on("click", nameSpace.myFunc);

....

nameSpace = {

    myFunc: function(){
       this.anotherFunc();
    }

}

that will throw error.

Solution 1

You may change this.anotherFunc() with nameSpace.anotherFunc()

Solution 2

You might change

$(el).on("click", nameSpace.myFunc);
// to ----->
$(el).on("click", function(){ nameSpace.myFunc(); }  );

Upvotes: 0

bevacqua
bevacqua

Reputation: 48476

If you want it to be shorter maybe you should consider the following pattern:

Javascript Design Pattern Suggestion

basically for your example:

var myNameSpace = (function()
{
    function _myFirstFunction(){
        alert("Hello World!");
    }

    function _mySecondFunction(){
        _myFirstFunction();
    }

    return {
        MyFirstFunction : _myFirstFunction,    
        MySecondFunction : _mySecondFunction
    };
})();

I find this to be the cleanest pattern, also providing "private/public" variables in javascript that's otherwise pretty much impossible

Upvotes: 2

Bryan J Swift
Bryan J Swift

Reputation: 1499

In some cases the this keyword should work fine. If you explicitly call myNameSpace.mySecondFunction() then this.myFirstFunction() will execute as intended.

If you are using myNameSpace.mySecondFunction as an event handler it likely will not. In the case of an event handler you would need some way to refer to the namespace you want to use. A lot of JavaScript frameworks provide a way to define what the this keyword refers to. For example, in MooTools you can do myNameSpace.mySecondFunction.bind(myNameSpace) which will cause this to refer to myNameSpace inside mySecondFunction. If you are not using a framework you could make your event handler an anonymous function like:

document.getElementById('myId').addEventListener('click', function(e) {
  myNameSpace.mySecondFunction.call(myNameSpace);
});

For more information on the call method I would refer to the MDC page for the call function or you could use apply which behaves similarly to call but passing an array of arguments for the second paramter rather than having a varargs like approach for additional parameters.

All of these suggestions are predicated on defining your namespace as @Harnish suggested:

var myNameSpace = {
  myFirstFunction: function(){
    alert("Hello World!");
  },
  mySecondFunction: function(){
    this.myFirstFunction();
  }
}

For more information about JavaScript function binding I'd highly suggest reading Justin's article on Function scope and binding in JavaScript

Upvotes: 0

Bryan
Bryan

Reputation: 2870

As written in your example code, this.myFirstFunction() would work. Your code is likely simplified to illustrate your problem, so it would probably help to see the actual code to tell why it doesn't work with this.

One possible reason that it fails would be if the code where you call this.myFirstFunction() is inside a closure. If so, this would be a reference to the closing function, not your namespace and would therefore fail. See here for a contrived example based on your code to see what I mean. Again, having a look at the actual code would probably be helpful to diagnose what's going on.

Upvotes: 12

Hamish
Hamish

Reputation: 23316

Your suggestion to use 'this' should work. i.e.:

var myNameSpace = {
    myFirstFunction: function(){
        alert("Hello World!");
    },
    mySecondFunction: function(){
        this.myFirstFunction();
    }
}

Result:

myNameSpace.mySecondFunction() // "Hello World!".

Upvotes: 2

Related Questions