0

I originally had code like that below, where I had nothing in the global namespace and I was able to call functions in obj2 from obj1 and vice versa. And all was well.

(function() {
    var obj1 = {
        obj1_f1 : function() {
        },
        obj1_f2 : function() {
            obj2.obj2_f1();
        }
    };
    var obj2 = {
        obj2_f1 : function() {
            obj1.obj1_f1();
        },
        obj2_f2 : function() {
        }
    };
    $(document).ready(function () {
        obj1_f1();
    });
})();

But now I need to call a function in the obj1 object from the global context, so I have to introduce a global object:

var com_mycompany_make_sure_unique = new function() {
    // use 'this.' so that obj1 is not in the global namespace
    this.obj1 = {
        obj1_f1 : function() {
        },
        obj1_f2 : function() {
            com_mycompany_make_sure_unique.obj2.obj2_f2();
        }
    };
    this.obj2 = {
        obj2_f1 : function() {
            com_mycompany_make_sure_unique.obj1.obj1_f1();
        },
        obj2_f2 : function() {
        }
    };

    $(document).ready(function () {
        com_mycompany_make_sure_unique.obj1.obj1_f1();
    });
};

but I'm not overly happy with that - I have to prepend all function calls with my global object name when calling functions across obj1 and obj2. I think I'm missing a trick.

Thanks for any help,

Paul

3
  • I may be wrong but if I understood correctly this looks like a circular reference and most likely it is a design error. Commented Dec 2, 2014 at 15:49
  • 1
    The first function won't work; the "ready" handler should probably be calling obj1.obj1_f1() because there's no visible symbol at that point called just obj1_f1. Commented Dec 2, 2014 at 15:50
  • @Pointy: Well, the symbol is visible, but its value is undefined. :-) Commented Dec 2, 2014 at 16:00

1 Answer 1

2

You can do this (see comments):

var com_mycompany_make_sure_unique = function() {
    // Continue using variables as you were before
    var obj1 = {
        obj1_f1 : function() {
        },
        obj1_f2 : function() {
            obj2.obj2_f2();
        }
    };
    var obj2 = {
        obj2_f1 : function() {
            obj1.obj1_f1();
        },
        obj2_f2 : function() {
        }
    };

    $(document).ready(function () {
        obj1.obj1_f1();
    });

    // Return an object that can be used via the `com_mycompany_make_sure_unique` variable
    return {
        obj1: obj1,
        obj2: obj2
    };
}();

This is sometimes called the "revealing module pattern" because everything inside the outer anonymous scoping function is private, and then you "reveal" the parts you want to reveal by putting them on the object you return. If you only needed to expose obj1, for instance, and not obj2, you could do that:

return {
    obj1: obj1
};

My question, though, is why do you need to call functions from the global context? With modern event handling and Asynchronous Module Definition loaders like RequireJS, the only global you should really require (ugh) is the AMD function(s).


Side note: I replaced your var ... = new function() { ... }; with var ... = function() { ... }(); There's no need to use new here, and doing so can tend to confuse people (and gives the resulting object an extra prototype it doesn't need). But you could use your original form if you like, just change the end to

this.obj1 = obj1;
this.obj2 = obj2;

...rather than returning an object.

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

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.