Wednesday, September 24, 2014

JavaScript Pollution

Intro

Everyone knows pollution is bad. It turns rain acidic, makes our roads look terrible, fouls our drinking water, and can cause naming conflicts in our JavaScript code. What? Yeah that's right, our JavaScript code. Write your congressperson I tellz ya! It's a huge problem. But don't fret, there are ways you can mitigate this danger to our very way of life, and I'll show you 2 simple things you can do to lower your global-carbon-JavaScript-namespace footprint.

Que?

Polluting the global namespace is a common term for a common practice in JavaScript. When I create a plain old function in JavaScript such as the following:

function someFunc() {
    window.alert('some text!');
}

someFunc();

I've now committed a cardinal sin, right up there with sloth and eating the last Oreo. I've polluted the global namespace! See how the function someFunc is just floating around in the ether, available to be called from anywhere and without a class or namespace prefix necessary? This is what polluting the global namespace is. This might not seem like a big deal to you. I mean, so what? You're the one writing this code and it's not like you're going to conflict with your own function names right? Well JavaScript is a very open language, and many people these days use multiple 3rd party libraries. Now pretend all these 3rd party libraries are also polluting the global namespace. You'd have naming conflicts between the 3rd party libraries and with your own local code, and that would be quite painful to deal with. How can you, the lowly programmer, prevent your own code from polluting the global namespace? For those of you used to C#, the answer should come naturally: namespaces and classes!

Namespace Example

There are many ways to skin a platypus, and there are many ways to create a namespace in JavaScript. I won't cover all of them, I'll just show you my favorite:

var MyNamespace = MyNamespace || {};

MyNamespace.myInt = 3;


It doesn't get much simpler than that. The first line of code creates our "namespace". It's not really a namespace as JavaScript doesn't support namespaces, but we can useMyNamespace quite similarly to how we us namespaces. We can even nest them if we feel like it. The 2nd line of code just adds a variable named myInt to our namespace. If you want to later created a 2nd javascript file and reuse your namespace, all you have to do is copy that first line to the top of your new file. The magic here is that when we declare MyNamespace, we set it to itself, or if it's undefined, we set it to an empty new object. So if you do this in 1 file or 50 files, you'll either create a new "namespace" object or assign the namespace object to itself, so it works quite easily.

Class Example

Classes take a little more work but they're still not too bad. Here's an example of how to define a class, create an instance of it, and then use it:

//set namespace
var MyNamespace = MyNamespace || {};

//create our class in the namespace
MyNamespace.MyClass = function () {
    this.stringProp = "some string";
    this.intProp = 42;
};

//add the method myFunc to our class
MyNamespace.MyClass.prototype.myFunc = function () {
    window.alert(this.stringProp + "::" + this.intProp);
};

//create a method within the namespace (but not in the class) that creates an instance of the class, sets a property of the object, and calls a method of the object
MyNamespace.doThisStuff = function () {
    var myObj = new MyNamespace.MyClass();
    myObj.stringProp = "yep, still a string";
    myObj.myFunc();
};


The first chunk of code you've seen before; it sets up our namespace.
The 2nd chunk of code defines the class. More accurately, it defines the constructor for our class, within which we also define our class properties stringProp and intProp. We set them to default values too.
The 3rd chunk adds the method myFunc to our class. I won't get into the keyword "prototype", but suffice it to say you should use it when setting methods of your classes so that the method will be instance-level instead of static/class-level.
The 4th chunk of code is a namespace-level method that creates an instance of our class via the new keyword, sets a property value on the instance, and then calls a method on the instance.

All you would have to do now is setup an html file to call your code and you're good to go. You can create as many instances of the class MyClass, which is defined in the namespace MyNamespace as you want to. Have at it!

Summary

I hope you can see the great benefits of using classes and namespaces in JavaScript (well, the strange equivalent of them anyways). Polluting the global namespace can be a tricky problem if you run across it, and preventing the problem is quite easy. Plus it makes your code easier to organize, and in my opinion easier to read. Try it out! It's easy I promise, it just takes a little practice.

What's Next?

  • Read further on objects in JavaScript, and how JavaScript doesn't really support namespaces and classes (we just faked it).
  • Do some more reading on other ways people have come up with to emulate namespaces and classes in JavaScript. You might find one that you like better than what I chose!
  • Learn how to nest your namespaces.
  • Learn how to do inheritance. It's kind of tricky for a language that doesn't really support classes.
  • There is another way to create an instance of a class, Object.create. Read about it.

Resources

Introduction to Object-Oriented JavaScript
My Code

No comments:

Post a Comment