0

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!

2
  • No. Any attempt to do this is a dirty hack. Commented Aug 24, 2011 at 22:07
  • Deleted my answer because I didn't notice you were calling Foo as a constructor. Using this.bar() does not work as you stated because this in Foo, and therefore the callback, is not ns, but rather the new object being created by the constructor. jsbin.com/otegos/edit#javascript,live Commented Aug 24, 2011 at 22:21

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

5 Comments

Unless the parent object is window? Just wondering why it works for objects defined in the global scope.
@Paul because window is special & ugly. Your accessing global objects. The fact that window is also the global container that contains all global objects by name is a seperate thing
Javascript !== Java??? What have you been smoking? They are essentially exactly the same, except JS is interpreted. And JS has no strong typing. And JS has no classes. And ...
window is not part of JS as such. It's part of most commonly used implementation (i.e. built-in browser JS) and can be thought of as part of a 'framework' of sorts, that make programmer's life a bit easier (or more miserable depending on occasion)
@trinithis: ... and programming in JavaScript is actually fun? ;)
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.