Best Practices -
JavaScript Programming
Part
2
Object Oriented Programming
The advantages of OO Programming vs. Procedural Programming
are well known but exceed the scope of this post. While JavaScript is not a
classic OO language such as Java/C++/C#, it holds many OO capabilities.
Although the
syntax of OO programming in JS can be confusing at first, it becomes a very handy
and easy to use feature once you get used to it.
Objects(Classes):
As a prototype based language
JavaScript does not have classes, therefore it does not
contain a ‘class’ statement. Instead, classes can be simulated through
functions.
Let’s
observe the following example:
function ListItem() { }
We’ve just simulated a class called ListItem. Cool hah?
Objects and Constructors:
Instantiating is done using the ‘new’ keyword. The function itself is
used as a constructor.
var li = new
ListItem();
Pay Attention: calling the constructor function without the 'new' keyword will result in a regular execution of the function instead of creating a new instance.
Members/Properties:
function ListItem(headline) {
this.Headline = headline;
}
var headLineItem = new
ListItem("HeadLine");
Here the
constructor receives one parameter. The HeadLine property is initialized.
Methods:
function ListItem(headline) {
this.Headline = headline;
this.ToString = function
() {
return "ListItem:"
+ this.Headline;
}
}
var headlineItem = new
ListItem("HeadLine");
var stringRepresentation = headlineItem.ToString();
I think we
got the idea…
Prototype:
Much like
the extension methods mechanism in C#, JavaScript allows the programmer to
extend the functionality of an object outside its constructor's scope. This is done using prototype.
For
instance, let’s take the object from above and add to it the ability to alert
its headline to the screen:
ListItem.prototype.AlertHeadline = function () {
alert(this.Headline);
}
What we did
here was to add the method AlertHeadline() to the object ListItem.
We can now
run it from any ListItem instance:
headLineItem.AlertHeadLine();
*Note: prototyping should be used wisely.
There’s no sense in extending a local object that exists in your own code with a
method written in a different place – just add the method to the constructor function's scope. In case we choose to extend an external
object, we should keep all of our prototype extension methods in a single place
(Extensions.js file for example). Otherwise, it can be a major headache trying
to track down a prototype method, especially in complex environments that
contain a lot of code.
A great example
for the use of prototype is the String.format extension:
String.prototype.format = function () {
var str = this;
var i = arguments.length;
while (i--) {
str = str.replace(new RegExp('\\{' + i + '\\}',
'gm'),
arguments[i]);
}
return str;
};
JQuery
JavaScript
is executed by the built in interpreters of browsers. Though there are
standards, different browsers may execute the same JS code slightly different from
one another. To ensure the correct execution of your JS code it is advised to
use JQuery wherever possible, especially for DOM traversal and AJAX.
Final Words
As I said
before, all that is written here comes from my own personal experience. These
practices work for me and will hopefully work for some of you.
Enjoy.
Back to: Part 1
Discussing classes while talking about JavaScript just means that you think in Java/C++/C#/... and not really (actually , really not) understand this language.
ReplyDeleteYoav -
ReplyDeleteI personally don't care if someone refers to a constructor as a class, as long as they know how JS objects work, and that a constructor is just another way to create objects.
For new comers to the language, I agree that the term could be confusing.
Thank you for your comment (I guess…). As stated in the first sentence of the section: “As a prototype based language JavaScript does not have classes”. It has only objects. Having said that, writing Object Oriented code by simulating classes using functions can be a very good practice. Since the title of the post is “Best Practices –JavaScript Programming” and not “Discover The JavaScript Internals”, I think my explanation was sufficient. You’re welcome to disagree.
ReplyDeleteBasically, talking about classes seems to me as a misleading path when trying to educate about JavaScript, since it abstracts out the language's intense dynamic nature.
ReplyDeleteSaying that a function is a class is a risky thing. The fact that what a function does depends on the way it is called is something that any JS developer should know before he/she writes a single line of code. I don't see it as an internal detail, but as a crucial part of the language - think of the effects of calling that function when the developer had mistakenly forgot to use the 'new' keyword.
I do appreciate the effort in writing "best practices" posts - especially in a language which is filled with mine fields, but such posts should tell you how to avoid these mine fields, not how to ignore them.
I see your point regarding the confusion around the constructor call. An update was added.
ReplyDeleteThanks.
Still there is no harm with abstracting as long as you understand the nature of the abstraction. Actually, in most complex javascript applications you'll see Classes and Instances abstractions (see prototype.js and ember.js).
ReplyDeleteI would strongly recommend working with such frameworks (ember.js is amazing) in order to avoid problems like mentioned in the comments.