Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Initializing a global namespace object

Reply
Thread Tools

Initializing a global namespace object

 
 
Stanimir Stamenkov
Guest
Posts: n/a
 
      07-26-2010
As the number of utility functions I write increases I've started to
use a global variable acting as namespace for my functions. Given
my functions are spread in couple of .js files and the order of
loading is not significant (documents may include random combination
of the files) I've wondered how it is best to initialize the
namespace object.

I generally use the following construct in my .js files:

(function () {
if (typeof MYNS === "undefined") {
MYNS = { };
}
// Add stuff to MYNS...
}());

But then running this through JSLint tells me: "'MYNS' is not
defined". Changing the code to:

(function () {
if (typeof this.MYNS === "undefined") {
this.MYNS = { };
}
// Add stuff to MYNS...
}());

results in no JSLint errors but then it lists 'MYNS' as member and
not a global variable, if it matters at all. Which of the both
forms is recommended? Should I just tell JSLint 'MYNS' is a
predefined global?

--
Stanimir
 
Reply With Quote
 
 
 
 
Asen Bozhilov
Guest
Posts: n/a
 
      07-26-2010
Stanimir Stamenkov wrote:

> results in no JSLint errors but then it lists 'MYNS' as member and
> not a global variable, if it matters at all. *Which of the both
> forms is recommended? *Should I just tell JSLint 'MYNS' is a
> predefined global?


Both are not good. First, because use undeclared assignment. In the
second approach the problem is in ES5 environment. The `this'
associated with that execution context in strict mode must be
`undefined'. So you will get TypeError.

I don't see any benefits by your code. The order of loading is always
mandatory and the users of your code must be know that. I have never
liked such a definition of a namespace. If I want namespace I do:

var MYNS = {};

It's enough. Should I care about third party conflicts? I don't think
so. If there are third party conflicts this means wrong usage of my
code and my recommendations. And for environment which I suggest to be
used this code I am sure that `MYNS' does not refer both host or built-
in object.

What is your native language? Is it Bulgarian?
 
Reply With Quote
 
 
 
 
Ry Nohryb
Guest
Posts: n/a
 
      07-26-2010
On Jul 26, 2:26*pm, Stanimir Stamenkov <(E-Mail Removed)> wrote:
> As the number of utility functions I write increases I've started to
> use a global variable acting as namespace for my functions. *Given
> my functions are spread in couple of .js files and the order of
> loading is not significant (documents may include random combination
> of the files) I've wondered how it is best to initialize the
> namespace object.
>
> I generally use the following construct in my .js files:
>
> (function () {
> * * *if (typeof MYNS === "undefined") {
> * * * * *MYNS = { };
> * * *}
> * * *// Add stuff to MYNS...
>
> }());
>
> But then running this through JSLint tells me: "'MYNS' is not
> defined". *Changing the code to:
>
> (function () {
> * * *if (typeof this.MYNS === "undefined") {
> * * * * *this.MYNS = { };
> * * *}
> * * *// Add stuff to MYNS...
>
> }());
>
> results in no JSLint errors but then it lists 'MYNS' as member and
> not a global variable, if it matters at all. *Which of the both
> forms is recommended? *Should I just tell JSLint 'MYNS' is a
> predefined global?


Use window.MYNS instead of this.MYNS, and, in order to avoid
overwriting/destroying a possibly pre-existing/previously-defined
MYNS :

window.MYNS= window.MYNS || {};

JSLint then won't complain because global vars are properties of the
global object, and the 'window' and 'self' globals are references to
the Global Object itself:

GlobalObject.window === GlobalObject.self === GlobalObject ===
(function(){return this})()

and thus window.someGlobalVarName is only an explicit way of saying
"hey, this is a global var !".
--
Jorge.
 
Reply With Quote
 
Stanimir Stamenkov
Guest
Posts: n/a
 
      07-26-2010
Mon, 26 Jul 2010 12:47:48 -0700 (PDT), /Asen Bozhilov/:

> Both are not good. First, because use undeclared assignment. In the
> second approach the problem is in ES5 environment. The `this'
> associated with that execution context in strict mode must be
> `undefined'. So you will get TypeError.


O.k. I understand. I generally don't have such advanced knowledge of
JavaScript. Do you know which browsers currently implement the ES5
specification and support strict mode?

> I don't see any benefits by your code. The order of loading is always
> mandatory and the users of your code must be know that. I have never
> liked such a definition of a namespace. If I want namespace I do:
>
> var MYNS = {};
> (...)


The problem is I have a bunch of .js files which happen to be written by
multiple people and contain just "flying" global functions, and I want
to convince all the guys writing them we should at least start using a
separate space than the global object. Then we could also start
thinking of giving the code finer modularization.

So until we start making more sense of the code organization I want to
introduce a single object acting as global namespace for our own code.
And yes, the files are not loaded in random order but then different
sets of them is included in different documents, so I want more
foolproof fix for the initial namespace problem hence I need to set it
up independently in every file, but in non-destructive manner.

> What is your native language? Is it Bulgarian?


Yes, I'm native Bulgarian speaking.

--
Stanimir
 
Reply With Quote
 
Ry Nohryb
Guest
Posts: n/a
 
      07-26-2010
On Jul 27, 1:32*am, Stanimir Stamenkov <(E-Mail Removed)> wrote:
> Mon, 26 Jul 2010 20:18:00 +0000 (UTC), /Ry Nohryb/:
>
> > Use window.MYNS instead of this.MYNS, and, in order to avoid
> > overwriting/destroying a possibly pre-existing/previously-defined MYNS :

>
> > window.MYNS= window.MYNS || {};

>
> I decided to use this.MYNS instead of window.MYNS as in the given case,
> and as far as my knowledge goes, 'this' should refer to the global
> object and I don't really care (or want to depend) it happens to be the
> 'window' one having a self references as 'window' and 'self'
> properties. *But as Asen Bozhilov pointed in another reply, I now see
> 'this' is no safer to use. *I currently have no knowledge of ES5 and how
> browsers scripts should operate in that environment, but I'll probably
> stick with your suggestion until I get to understand more.
>
> > JSLint then won't complain because global vars are properties of the
> > global object, and the 'window' and 'self' globals are references to
> > the Global Object itself:

>
> > GlobalObject.window === GlobalObject.self === GlobalObject ===
> > (function(){return this})()

>
> > and thus window.someGlobalVarName is only an explicit way of saying
> > "hey, this is a global var !".

>
> JSLint also complained about 'window' not defined until I tell it
> 'window' is a predefined symbol explicitly, although I had checked the
> "Assume a browser" option, also. *Is it o.k. if I do:
>
> (function () {
> * * *var MYNS = window.MYNS = window.MYNS || { };
> * * *MYNS.fooBar = function () {
> * * * * *// ...
> * * *};
>
> }());
>
> so I don't have to qualify every MYNS reference in the closure, next?


If this code runs at the top level (if it's not wrapped in an eval()
nor inside any other function), I'd write it so:

var MYNS= window.MYNS || { };
(function () {

//Use MYNS here freely, it's already a global.

})();

The window.MYNS in the var MYNS declaration is there just to make
JSLint happy. If JSLint doesn't "hurt your feelings", you can write it
without the window. :

var MYNS= MYNS || { };

But it (JSLint) will probably complain about the use of an undeclared
MYNS because it's being used prior to its declaration.
--
Jorge.
 
Reply With Quote
 
Ry Nohryb
Guest
Posts: n/a
 
      07-27-2010
On Jul 27, 1:49*am, Ry Nohryb <(E-Mail Removed)> wrote:
>
> But it (JSLint) will probably complain about the use of an undeclared
> MYNS because it's being used prior to its declaration.


Well, I mean, at that point it's -probably- undefined, but not
undeclared.
--
Jorge.
 
Reply With Quote
 
JR
Guest
Posts: n/a
 
      07-27-2010
On Jul 26, 9:26*am, Stanimir Stamenkov <(E-Mail Removed)> wrote:
> As the number of utility functions I write increases I've started to
> use a global variable acting as namespace for my functions. *Given
> my functions are spread in couple of .js files and the order of
> loading is not significant (documents may include random combination
> of the files) I've wondered how it is best to initialize the
> namespace object.
>
> I generally use the following construct in my .js files:
>
> (function () {
> * * *if (typeof MYNS === "undefined") {
> * * * * *MYNS = { };
> * * *}
> * * *// Add stuff to MYNS...
>
> }());
>
> But then running this through JSLint tells me: "'MYNS' is not
> defined". *Changing the code to:
>
> (function () {
> * * *if (typeof this.MYNS === "undefined") {
> * * * * *this.MYNS = { };
> * * *}
> * * *// Add stuff to MYNS...
>
> }());
>
> results in no JSLint errors but then it lists 'MYNS' as member and
> not a global variable, if it matters at all. *Which of the both
> forms is recommended? *Should I just tell JSLint 'MYNS' is a
> predefined global?
>
> --
> Stanimir


Hi,
I think of (function () {})() as a means of avoiding global variables.
But if you want / need a global variable then you should follow
Jorge's advice or do that:

(function() {
var global = this;
global.MYNS = { };
// to be continued.
})();

But it seems easier to write only var MYNS = { } than the module
pattern (function() {})()

--
JR
 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      07-27-2010
On Jul 26, 10:26*pm, Stanimir Stamenkov <(E-Mail Removed)> wrote:
> As the number of utility functions I write increases I've started to
> use a global variable acting as namespace for my functions. *Given
> my functions are spread in couple of .js files and the order of
> loading is not significant (documents may include random combination
> of the files) I've wondered how it is best to initialize the
> namespace object.
>
> I generally use the following construct in my .js files:
>
> (function () {
> * * *if (typeof MYNS === "undefined") {
> * * * * *MYNS = { };


Don't be coy about creating global variables. If you want to create
one, declare it right up front. Just before the anonymous function,
use:

var MYNS;


Note that if MYNS already exists, the extra variable declaration has
no impact, so it is absolutely safe. Anyone reading your code will see
it right at the top and know it's yours.


> * * *}
> * * *// Add stuff to MYNS...
>
> }());
>
> But then running this through JSLint tells me: "'MYNS' is not
> defined". *Changing the code to:
>
> (function () {
> * * *if (typeof this.MYNS === "undefined") {
> * * * * *this.MYNS = { };
> * * *}
> * * *// Add stuff to MYNS...


Just declare it before the function.


> }());
>
> results in no JSLint errors but then it lists 'MYNS' as member and
> not a global variable, if it matters at all. *Which of the both
> forms is recommended? *Should I just tell JSLint 'MYNS' is a
> predefined global?


If you want MYNS to be a native Object object, then you should test
explicitly for that. If you want to be strict, then the following
should run as global code:

var MYNS;
if (typeof MYNS != 'object') {
MYNS = {};
}

Now you know excatly what MYNS is (and may have stomped on someone
else's MYNS, but that's for the user of your code to fix).

Don't fall for junk like the following (which is in a commercial
product in wide use where I work):

if (dwr == null) var dwr = {};

Which infers that variables can be conditionally decalred (they can't)
and depends on the truthiness of undefined == null. The author
probably should have written:

var dwr;
if (typeof dwr == 'undefined') {
dwr = {};
}


Anyhow, it is probably sufficient to use the following as global code:

var MYNS = MYNS || {};


--
Rob
 
Reply With Quote
 
Scott Sauyet
Guest
Posts: n/a
 
      07-27-2010
On Jul 26, 8:26*am, Stanimir Stamenkov <(E-Mail Removed)> wrote:
> As the number of utility functions I write increases I've started to
> use a global variable acting as namespace for my functions. *Given
> my functions are spread in couple of .js files and the order of
> loading is not significant (documents may include random combination
> of the files) I've wondered how it is best to initialize the
> namespace object.


I've had to do this a number of times recently, and this has served my
purposes well:

var MYNS = MYNS || {};

at the top of each JS file that uses the namespace. And I simply tell
JSLint that this is a global variable.

When I can't put the global namespace in a JSLint configuration file,
I often format it as

/* global MYNS */ var MYNS = MYNS || {};

to keep it to a single line.

That seems fairly simple, and I don't know if there are any underlying
issues that I haven't considered, but it works well for me.

--
Scott
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      07-27-2010
On Jul 26, 4:18*pm, Ry Nohryb <(E-Mail Removed)> wrote:
> On Jul 26, 2:26*pm, Stanimir Stamenkov <(E-Mail Removed)> wrote:
>
>
>
>
>
> > As the number of utility functions I write increases I've started to
> > use a global variable acting as namespace for my functions. *Given
> > my functions are spread in couple of .js files and the order of
> > loading is not significant (documents may include random combination
> > of the files) I've wondered how it is best to initialize the
> > namespace object.

>
> > I generally use the following construct in my .js files:

>
> > (function () {
> > * * *if (typeof MYNS === "undefined") {
> > * * * * *MYNS = { };
> > * * *}
> > * * *// Add stuff to MYNS...

>
> > }());

>
> > But then running this through JSLint tells me: "'MYNS' is not
> > defined". *Changing the code to:

>
> > (function () {
> > * * *if (typeof this.MYNS === "undefined") {
> > * * * * *this.MYNS = { };
> > * * *}
> > * * *// Add stuff to MYNS...

>
> > }());

>
> > results in no JSLint errors but then it lists 'MYNS' as member and
> > not a global variable, if it matters at all. *Which of the both
> > forms is recommended? *Should I just tell JSLint 'MYNS' is a
> > predefined global?

>
> Use window.MYNS instead of this.MYNS, and, in order to avoid
> overwriting/destroying a possibly pre-existing/previously-defined
> MYNS :
>
> window.MYNS= window.MYNS || {};


You've finally lost it, haven't you Jorge?

var MYNS;

if (!MYNS) {
MYNS = {};
}

Or:-

var MYNS;

MYNS = MYNS || {};


>
> JSLint then won't complain because global vars are properties of the
> global object, and the 'window' and 'self' globals are references to
> the Global Object itself:


Not that it matters a whit, but last I checked, JSLint decried the use
of - window - as an "implied global". (!)

>
> GlobalObject.window === GlobalObject.self === GlobalObject ===
> (function(){return this})()


As you've been told a thousand times, that proves nothing.

>
> and thus window.someGlobalVarName is only an explicit way of saying
> "hey, this is a global var !".


Get better Jorge!
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Adding an object to the global namespace through " f_globals" isthat allowed ? Stef Mientki Python 1 07-03-2009 12:50 PM
use object method without initializing object Reckoner Python 3 04-15-2008 04:25 PM
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 1 10-25-2006 06:50 PM
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 0 10-25-2006 01:04 PM
Initializing a static variable inside a namespace ik C++ 2 09-22-2004 07:53 AM



Advertisments