What Does It Mean Global Namespace Would Be Polluted

What does it mean global namespace would be polluted?

Quick Note On Garbage Collection

As variables lose scope, they will be eligible for garbage collection. If they are scoped globally, then they will not be eligible for collection until the global namespace loses scope.

Here is an example:

var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}

Adding this to your global namespace (at least for me) should ad 10,000 kb of memory usage (win7 firefox) which will not be collected. Other browsers may handle this differently.

Whereas having that same code in a scope which goes out of scope like this:

(function(){
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
})();

Will allow arra to lose scope after the closure executes and be eligible for garbage collection.

Global Namespace Is Your Friend

Despite the many claims against using the global namespace, it is your friend. And like a good friend, you should not abuse your relationship.

Be Gentle

Don't abuse (usually referred to as "polluting") the global namespace. And what I mean by do not abuse the global namespace is - do not create multiple global variables. Here is a bad example of using the global namespace.

var x1 = 5;
var x2 = 20;
var y1 = 3
var y2 = 16;

var rise = y2 - y1;
var run = x2 - x1;

var slope = rise / run;

var risesquared = rise * rise;
var runsquared = run * run;

var distancesquared = risesquared + runsquared;

var distance = Math.sqrt(dinstancesquared);

This is going to create 11 global variables which could possibly be overwritten or misconstrued somewhere.

Be Resourceful

A more resourceful approach, which does not pollute the global namespace, would be to wrap this all in the module pattern and only use one global variable while exposing multiple variables.

Here is an example: (Please note this is simple and there is no error handling)

//Calculate is the only exposed global variable
var Calculate = function () {
//all defintions in this closure are local, and will not be exposed to the global namespace
var Coordinates = [];//array for coordinates
var Coordinate = function (xcoord, ycoord) {//definition for type Coordinate
this.x = xcoord;//assign values similar to a constructor
this.y = ycoord;
};

return {//these methods will be exposed through the Calculate object
AddCoordinate: function (x, y) {
Coordinates.push(new Coordinate(x, y));//Add a new coordinate
},

Slope: function () {//Calculates slope and returns the value
var c1 = Coordinates[0];
var c2 = Coordinates[1];
return c2.y - c1.y / c2.x - c1.x;//calculates rise over run and returns result
},

Distance: function () {
//even with an excessive amount of variables declared, these are all still local
var c1 = Coordinates[0];
var c2 = Coordinates[1];

var rise = c2.y - c1.y;
var run = c2.x - c1.x;

var risesquared = rise * rise;
var runsquared = run * run;

var distancesquared = risesquared + runsquared;

var distance = Math.sqrt(distancesquared);

return distance;
}
};
};

//this is a "self executing closure" and is used because these variables will be
//scoped to the function, and will not be available globally nor will they collide
//with any variable names in the global namespace
(function () {
var calc = Calculate();
calc.AddCoordinate(5, 20);
calc.AddCoordinate(3, 16);
console.log(calc.Slope());
console.log(calc.Distance());
})();

What is namespace pollution?

A namespace is simply the space in which names exist (seems obvious enough now).

Let's say you have two pieces of code, one to handle linked lists, the other to handle trees. Now both of these pieces of code would benefit from a getNext() function, to assist in traversal of the data structure.

However, if they both define that function with the same name, you may have a clash. What will your compiler do when you enter the following code?

xyzzy = getNext (xyzzy);

In other words, which getNext() do you actually want to use? There are numerous ways to solve this, such as with object-oriented code, where you would use:

xyzzy = xyzzy.getNext();

and that would auto-magically select the correct one by virtue of the fact you've specified the type via the variable xyzzy itself.

But, even with mostly-OO code, there may be situations where you have a conflict, and that's where namespaces enter the picture. They allow you to place the names into their own area so as to distinguish them.

C++, as one example, places all its standard library stuff into the std namespace. If, for some reason, you need an fopen() or rand() function that works differently from the one in the library, you can place it in your own namespace to keep them separate.

Now that describes namespace clashes. Technically, namespace pollution is simply leaving your symbols in a namespace where they shouldn't really be. This doesn't necessarily lead to clashes but it makes it more likely.


The reason why making a method static (in C-like languages) has to do with the names being made available to the world outside the given translation unit (when linking, for example). With the code:

int get42 (void) { return 42; }
int main (void) { return get42(); }

both of those functions are made available to the linker.

Unless you have a need to call get42() from somewhere else, making it static:

static int get42 (void) { return 42; }
int main (void) { return get42(); }

will prevent it from polluting the namespace maintained by the linker – in C, applying the static qualifier to a file-level object or function gives it internal linkage.

It's similar to the C++ namespaces in that you can have a static int get42() in four hundred different source files and they won't interfere with each other.

What does it mean to pollute the global namespace ?

Ruby has a singular root namespace shared by all code and any constants and globals you define there are universal through the whole application. This makes conflict inevitable if you're not careful about namespacing things.

The module construct is there as a namespace primitive, all constants will be local to that, all classes defined within it. You can also use a class as a namespace if you prefer, it's up to you.

Forcing the include of something into the root namespace is a big problem. That's usually only done in quick scripts that are fairly tiny and self-contained. That's a bad habit to get into when you're doing anything non-trivial as it mashes together all the constants and methods in those two contexts, potentially over-writing them.

Polluting the global namespace

I use namespaces for partitioning library code from application-specific code, and in a big project to partition the various modules that make up the project.

The global namespace is thus useful for application-specific types and functions that are used across multiple modules in the application.

So, if your MY_TYPE is used throughout your application, put it in the global namespace, otherwise put it in a named namespace.

Can I use $(document).ready(function() { ... }); to prevent global namespace pollution?

It's a good start, but you also need to ensure you don't create any global variables in the function. Setting strict mode (with "use strict";) should go most of the way for doing that. Checking every mention of window will go the rest of the way.

It does have the side effect of delaying execution of the code until the DOM is ready. That isn't always desirable. You might want to use a simple IIFE instead.

Does namespace pollution in Java or C# exist (like in C++)?

As already pointed out by others, the problem of namespace pollution is not as prominent in Java as it is in C++. The main reason why namespace pollution is a problem in C++ (and thus called "pollution" in the first place) is that it may cause errors in other modules. This is explained in more detail in Why is “using namespace std;” considered bad practice?.

(The concerning thing here is that this may not only refer to compile errors: For compile errors, you are forced to do something and to resolve ambiguities. The really concerning thing is that it may cause the code to still compile properly, but afterwards simply call the wrong functions!)


In Java, each import affects only the file in which it is contained. This means that the above mentioned pollution can still occur locally in one file. (One could say: It's only the problem of the author who actually caused the namespace pollution, which is just fair)

Analogously to the case in the above mentioned link: Imagine you are using two libraries, "foo" and "bar". And out of laziness (or lack of knowledge of best practices), you are using the wildcard imports:

import foo.*:
import bar.*:

class MyClass {
void someMethod() {

// Assume that this class is from the "foo" librariy, and the
// fully qualified name of this class is "foo.Example"
Example e = new Example();
}
}

Now imagine you upgrade your version of the "bar" library. And the new version contains a class called bar.Example. Then the above code will fail to compile, because the reference to the class Example is ambiguous.

The same problem can, by the way, also appear with static imports. It's a bit more delicate and subtle, and collisions are a bit more likely. That's why they say that you should use static imports very sparingly.


A side note: Of course, these collisions and ambiguities can easily be resolved. You can always use the fully qualified names instead. Most modern Java IDEs offer a functionality to organize/optimize the imports. For example, in Eclipse, you can always press CTRL+Shift+O, which will (depending on the settings in Preferences->Java->Code Style->Organize Imports) replace all wildcard imports with the individual ones.

JavaScript Avoiding the global namespace pollution by objects created using constructor pattern

Security issue as any one can create objects without namespace from console.

That's not an issue, anyone can create objects on your namespace from the console as well.

pollution of the global namespace since the Book() object is now visible in the global scope.
The library is actually under a namespace using a revealing module pattern.

If you are loading all those files as scripts then they will put the classes declared therein in the global namespace. It's unavoidable to use the global namespace somehow, but you can put all of your objects on that custom library namespace right away, using the revealing module pattern. You would need to wrap each of those files in an IEFE that attaches the respective class to City.Library:

City.Library.Book = (function() {
function Book (data) {
this.data = data;
}
Book.prototype.rent = function(name) {
console.log("Rent the book to " + name);
};
return Book;
}());

Alternatively, treat the files as modules (ES6 is preferred) and let a module loader/bundler do this work for you automatedly.



Related Topics



Leave a reply



Submit