1

I have a very large javascript file: it's over 9,000 lines. The code looks like this:

var GlobalVar1 = "";
var GlobalVar2 = null;

function A() {...}

function B(SomeParameter) {...}

I'm using the google compiler and the global variables and functions get renamed a,b,c... and there's a good change that there might be some collision later with some outside code.

What I want to do is have my code organized like the jquery library where everything is accessible with $. Is there a way to namespace my code so that everything is behind a # character for example.

I'd like to have this to call my code:

#.GlobalVar
#.functionA(SomeParameter)

How can I do this?

Noelkd
  • 7,686
  • 2
  • 29
  • 43
frenchie
  • 51,731
  • 109
  • 304
  • 510
  • 2
    `#` is not a valid character in javascript identifier names. For "namespacing", look at the module pattern. Global variables are converted to local variablse and accessed through closures. Other variables and functions that should be available outside the "namespace" are held as properties of a single global object. – RobG Apr 11 '12 at 23:31
  • You can however use $ and _ which are both valid characters – Ryan McCarvill Apr 11 '12 at 23:44
  • duplicate of http://stackoverflow.com/questions/6549629/preferred-technique-for-javascript-namespacing (the linked question is more generally applicable) – Tim Abell Jun 15 '12 at 11:34

5 Answers5

3

Side note: the # character is not a valid variable name (see this question). Common 'shorthands' are the underscore _ and dollar $. I remember reading that the use of the dollar was meant for machine-generated code, but this has been largely disregarded, as you can see in jQuery.

The most familiar technique goes like this:

(function($) {
  $.a = function() { ... }
  $.b = 1000;
})(myNamespace);

myNamespace.a( ... );

Either which way, I think you'll have to have assignments in your code to some variable.

Alternatively you could specify something like a class:

function MyClass() {
  var f = 0;

  function a() { return f; }
  function b(value) { f = value; }
  function c() { f *= f; }

  this.get = a;
  this.set = b;
  this.square = c;
}

var myInstance = new MyClass();
Community
  • 1
  • 1
Yuval
  • 3,207
  • 32
  • 45
  • The $ character was intended for machine generated code in ECMA-262 ed 3. I think Prototype.js was the first to popularise its use in identifiers (possibly to mimick variable names in other languages that the original author was more familiar with). jQuery borrowed it from there. – RobG Apr 12 '12 at 00:22
3

You have to wrap all your library in a closure to protect your local variables. The members you want to be accessible globally you should assign to a global context object (in browser it is window).

(function(){
  var GlobalVar1 = "";
  var GlobalVar2 = null;

  function A() {...}

  function B(SomeParameter) {...}

  //  some function accessible globally with `window.C()` or just `C()`:
  window.C = function() {}
})();
Nikita Volkov
  • 42,792
  • 11
  • 94
  • 169
2
var $$ = {
    A: function() {
        alert('namespace rules!');
    },
    B: function() {
        alert('foo');
    }
}
$$.A();
$$.B();
​

LIVE DEMO

​​​​​​​​​​And so on...

Note that i changed from # to $$ because # in illegal toke for a variable name.

gdoron
  • 147,333
  • 58
  • 291
  • 367
  • @Thilo. It is an example... But I edited, just for you... :-) – gdoron Apr 11 '12 at 23:35
  • ok, and then in my code, instead of writing functionA(SomeParameter), I call the function by writing $.A and if I want to access my current global variable I write $.MyGlobal = 3; instead of MyGlobal = 3; ? If # is not good and $ is already taken, what's a good alternative? Is @ or % or & any better? – frenchie Apr 11 '12 at 23:37
  • @frenchie. What about `$$`? By the way, you can call the namespace `frenchie` which is a lot cooler then `$`... **:)** – gdoron Apr 11 '12 at 23:39
  • @Thio—what's your point? jQuery didn't care that Prototype.js had already popularised the use of the $ character when it adopted it too. Though I agree that it's a bad choice because it doesn't provide any information about what it means. – RobG Apr 12 '12 at 00:25
1
var # = {
    GlobalVar1: "",
    GlobalVar2: null,

    A: function() {

    },

    B: function(SomeParameter) {

    }
}
Ricardo Alvaro Lohmann
  • 26,031
  • 7
  • 82
  • 82
1

Another way - if you are already using Closure Compiler - would be to use its features to handle namespacing.

Example:

mylib.js:

goog.provide('mynamespace.whatever');

var globalVar1='foo';

mynamespace.whatever.functionA=function(txt){
    alert('A: '+txt+' '+globalVar1);
};

mynamespace.whatever.functionB=function(){
    alert('B: '+txt+' '+globalVar1);
};

main.js:

goog.require('mynamespace.whatever');

mynamespace.whatever.functionA('hello world');


And if you want to use unobfuscated functions/variables outside of the compiled code you can use:
goog.exportProperty(object, publicName, symbol)

and

goog.exportSymbol(publicPath, object, opt_objectToExportTo)

Have a look at: http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html

stewe
  • 41,820
  • 13
  • 79
  • 75