Paul
Paul

Reputation: 12440

Javascript Inheritance and this

Lets say I have a namespace called ns and ns has to functions on it:

ns = {};
ns.Foo = function(message, fn){
    this.message = message;
    fn.call(this);
};
ns.bar = function() {
    alert('Hello, world!');
};

And I call it like this:

var foo = new Foo('My Message', function() {
    bar();
});

I get an error saying bar() is undefined. But if I call it this way:

var foo = new Foo('My Message', function() {
    this.bar();
});

It works. Is there a way to structure my JavaScript so I can just call bar() without the this?

Thanks!

Upvotes: 0

Views: 102

Answers (2)

Wyatt
Wyatt

Reputation: 1366

What you're doing might be solved with closures.

JavaScript has no native concept of a namespace. There are namespace patterns people have used where they simply define a collection of tools inside a single object so that they don't pollute the global scope.

When you use "apply" or "call" the only difference is you've re-bound what "this" refers to as the function executes. You do not change it's parent scope.

Since these pseudo-namespaces are really just normal objects (not scopes) you cannot call its members without qualifying which object they belong to.

If you used a closure (which is a scope) instead of an object pseudo-namespace you could call members of the closure implicitly in functions that are defined inside the closure. For example:

var ns = {};
(function() {

    var Foo = ns.Foo = function(message, fn){
        this.message = message;
        fn.call(this);
    };

    var bar = ns.bar = function() {
        alert('Hello, world!');
    };

    var doStuff = ns.doStuff = function() {
        var myFoo = new Foo('My Message', function() {

            // "this" is unnecessary because bar is defined 
            // in this scope's closure.
            bar();
        });
    };

})();

var foo = new ns.Foo('My Message', function() {

    // Sill need "this" because bar is not defined in the scope
    // that this anonymous function is being defined in.
    this.bar();
});

You might also be able to use the "with" keyword, which explicitly modifies scope.

var foo = new ns.Foo('My Message', function() {
    with (this) {
        bar();
    }
});

Be warned though, the "with" keyword is generally frowned upon because it makes debugging difficult.

Upvotes: 0

Mchl
Mchl

Reputation: 62369

No. JavaScript is not Java. You need to specify object whose method you're calling.

Upvotes: 1

Related Questions