4

With the code below, other than specifying manually, is there a way to export only the functions and variables whose name doesn't start with an underscore?

var myapp = myapp || {};
myapp.utils = (function() {
  var
    CONSTANT_A = "FOO",
    CONSTANT_B = "BAR";

  function func() {}
  function _privateFunc() {}

  return {//return all variables and functions whose name does not have the "_" prefix.}
}());
tamakisquare
  • 16,659
  • 26
  • 88
  • 129
  • 4
    I don't think you can access the current stack frame except for `arguments`. If you're doing this by convention, you could flip it around, use an "exports" object called `_`, and export functions by doing `_.func = function() { ... }` – millimoose Jan 18 '13 at 21:40
  • 2
    Have you considered just setting up a separate object for all the functions and properties you wish to export? – kinsho Jan 18 '13 at 21:41
  • @millimoose - That's another approach that I have been considering. The only pitfall with that approach is that I would have to include the namespace name (`_` in this case) when accessing the variables in the functions. Ex. In `func()`, I would have to call `_.CONSTANT_A` instead of just `CONSTANT_A`. It's just a minor trouble, though. – tamakisquare Jan 18 '13 at 21:55
  • @kinsho - Your suggestion is basically similar to millimoose's. It looks like there's no ways to achieve what I am looking for, so I would probably need to go with your/millimoose's suggestion. Thx. – tamakisquare Jan 18 '13 at 21:59
  • 1
    Why not just define the functions you want to export as member methods of the returned object literal?? – natlee75 Jan 18 '13 at 22:00
  • You don't need to reference the namespace internally. Just create the return object first and when assigning variables assign them additionally as properties of the return object. Of course this won't work for any variable that references a primitive value as opposed to an object, function or array... – natlee75 Jan 18 '13 at 22:04
  • Okay, yeah, with those two constants you would need to reference via namespace since tide are just pointers to strings... sorry. – natlee75 Jan 18 '13 at 22:05

1 Answers1

6

Your idea requires being able to list all of the variables in the local scope. Unfortunately, JavaScript is not capable of doing that. See this related question.

There are two ways I've seen this be done:

1) Attach every variable when they're defined to an object to be exported:

var myapp = myapp || {};
myapp.utils = (function () {
    var exports = {};

    exports.CONSTANT_A = "FOO",
    exports.CONSTANT_B = "BAR";

    exports.func = function func() {}

    function _privateFunc() {}

    return exports;
}());

2) Or list all the exports at the end in an object literal:

var myapp = myapp || {};
myapp.utils = (function () {
    var 
       CONSTANT_A = "FOO",
       CONSTANT_B = "BAR";

    function func() {}
    function _privateFunc() {}

    return {
        CONSTANT_A: CONSTANT_A,
        CONSTANT_B: CONSTANT_B,
        func: func
    };
}());

I've seen both (and even mixes of the two) used in practice. The second may seem more pedantic, but also allows a reader to look at a single segment of code and see the entire interface returned by that function.

Community
  • 1
  • 1
George
  • 4,147
  • 24
  • 33