Saturday, March 15, 2008

JavaScript OO, part 1

According to Wikipedia, JavaScript is:

JavaScript is a scripting language most often used for client-side web development. It was the originating dialect of the ECMAScript standard. It is a dynamic, weakly typed, prototype-based language with first-class functions.

What is interesting in the previous definition is that there is no mention of object orientation. While there is nothing that says that you must write OO programs, it definitely one of the most common ways the programs are built these days. While there are other paradigms (functional programming, logic programming, structural programming, ...), JavaScript is nowadays mostly used in either simple imperative/structural or more complex OO-like ways. OO-like and not OO because JavaScript is not OO-capable language. For example, it doesn't support any protection mechanisms - everything is public. It supports something called prototype-based development. However, most people still call it OO - I suppose it's just "good enough".

Classes


Let's take a look at it. I will assume you are using JavaScript from within a standard browser. This is what it is:
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.display = function() {
alert('My name is ' + this.name + ' and I am ' + this.age);
}

function main() {
var person = new Person('Foo Bar', 33);
person.display();
}

If you somehow run method 'main' (e.g. by having it in your body onload event), you would see:
My name is Foo Bar and I am 33
in a dialog that pops up.

Although there is nothing even resembling a class in the above code if you compare it to e.g. Java classes, the above code actually is a basic example of a JavaScript class. The class is called Person.

Multiple constructors


In JavaScript, you cannot have multiple constructors as in other languages (e.g. C++, Java, C#, Ruby, Scala, ...). The reason for this is that classes are represented as functions. JavaScript doesn't have a concept of method overloading, as e.g. Java has. For example, in Java you can write:
public class MethodOverload {
public void method(int a) {}
public void method(String b) {}
public void method(double[] c) {}
}

The above code means that every instance of MethodOverload class have three methods with the same name. Which one gets called depends on the input parameters. If you would do the following:
MethodOverload mo = new MethodOverload();
mo.method(1);
mo.method("Hi");
mo.method(new double[]{ 1.0d, 2.0d });

then the above three calls would call the methods in order as given in the class definition. method(1) would call method(int a), method("Hi") would call method(String b) and method(new double[]{ 1.0d, 2.0d }) would call method(double[] c).

JavaScript, however, doesn't have this capability. In fact, in JavaScript, you can define multiple functions with the same name, but only the last one will "stick". To demonstrate this, try running the following:
function fun(a) {
alert('first: ' + a);
}

function fun(a) {
alert('second: ' + a);
}
fun(55);

The above code would display 'second: 55'. The interpreter will not even complain - the above code is valid. As if the first function hadn't even existed. You can circumvent this by using either optional named arguments or unnamed arguments. Optional named arguments means that you have one constructor which does all the work, while all other constructors are just the utility constructors for the user to be able to write the shorter code. For example:
function Person(firstName, lastName, sex, age, email, socialSecurityNumber, personalPhone, businessPhone, personalAddress, businessAddress, blogPage) {
this.firstName = firstName;
this.lastName = lastName;
if(typeof(sex) == 'undefined') {
// sex is not given.
this.sexDefined = 'no';
} else {
// sex is given.
this.sexDefined = 'yes';
}
// The same for all other optional arguments.
}

Assume that only firstname and lastName are required. You could instantiate it by:
var person = new Person('Foo', 'Bar');
alert([person.firstName, person.lastName, person.sexDefined]);
var person = new Person('Foo', 'Bar', 'male');
alert([person.firstName, person.lastName, person.sexDefined]);

The above would display 'Foo,Bar,no' and 'Foo,Bar,yes'. For the above two lines, you would accomplish the same thing in Java by writing two constructors:
public class Person {
private String firstName;
private String lastName;
private String sex;

public Person(String firstName, String lastName, String sex) {
this.firstName = firstName;
this.lastName = lastName;
this.sex = sex;
}

public Person(String firstName, String lastName) {
this(firstName, lastName, null);
}
}

The constructor would have to check whether all other things are undefined or not. A small digression - it is not enough to check for null in this case, for example:
function f(a) {
alert([a == null, typeof(a), typeof(a) == 'undefined']);
}

f(1);
f(null);

The above would display:
- f(1) => false, number, false
- f(null) => true, object, false
To check whether the argument is defined, always use typeof, except if you are sure that you will not have nulls as inupts.

The other option for multiple constructors is to use variable arguments:
function f() {
var s = '';
for(var i = 0; i < arguments.length; i++)
s += (i == 0 ? '' : ', ') + i + ': ' + arguments[i];
alert(s);
}

f('a')
f('b', 888)

The above would display:
- f('a') => 0: a
- f('b', 888) => 0: b, 1: 888

Using the above you could make the constructor take any parameter, decide what to do based on the length and types of the arguments, etc. Both options require checking whether the arguments are defined. The variable arguments is even more obscure, since you don't know how to call the constructor, except if you put a comment before it. That is maybe the reason why you don't see too much of these in real life, i.e. one constructor classes are the most common in JavaScript. For that reason, I will stick to one-constructor classes and occasionally use the optional arguments constructors.

Instance variables and methods


Back to the first example:
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.display = function() {
alert('My name is ' + this.name + ' and I am ' + this.age);
}

function main() {
var person = new Person('Foo Bar', 33);
person.display();
}

variables are used directly on an object, similar to way you do it in e.g. Java. When you say this.name, it refers to 'name' variable in the current instance. Note, however, that using of 'this' is obligatory, contrary to many situations in Java. When you say person.display(), it calls the method 'display' on the 'person' object, which happens to be the instance of the Person class.

JavaScript is both dynamically and weakly typed. This means that it resolves the type of the object in the runtime and you never supply it in the code. When you say
var person = new Person('Foo Bar', 33);
person.display();

it doesn't say anywhere in the code what person is - this is determined at runtime. You could do, for example, the following:
var person = new Person('Foo Bar', 33);
person = new SomeOtherClass();
person.display();

Depending whether SomeOtherClass has 'display' method, this will either call that method or raise an 'undefined function'-kind of error in JavaScript interpreter.

The same way you can have object methods, you can have object variables defined. This is something similar to class-level initialization in Java:
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.display = function() {
alert('My name is ' + this.name + ' and I am ' + this.age + '. I am from ' + this.planet);
}

Person.prototype.planet = 'Earth';

function main() {
var person = new Person('Foo Bar', 33);
person.display();
}

Note that 'planet' is the object-level, not class-level variable. To demonstrate that, try the following in main():
var person1 = new Person('Foo Bar', 33);
person1.planet = 'Mars';
person1.display();
var person2 = new Person('Baz Geez', 22);
person2.display();
person1.planet = 'Jupiter';
person2.planet = 'Neptune';
person1.display();
person2.display();

The output will be:
My name is Foo Bar and I am 33. I am from Mars
My name is Baz Geez and I am 22. I am from Earth
My name is Foo Bar and I am 33. I am from Jupiter
My name is Baz Geez and I am 22. I am from Neptune
As you can see, changing planet of person1 did not have any effect on planet of person2 and vice versa.

Class-level (a.k.a. static) methods and variables


You can have static methods and static variables in JavaScript - just omit the 'prototype' from the definition and that's it. For example:
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.findOldest = function(persons) {
if(persons.length == 0)
return null;

var oldest = persons[0];
for(var i = 1; i < persons.length; i++)
if(persons[i].age > oldest.age)
oldest = persons[i];
return oldest;
}

var persons = [
new Person('Very Young', 10),
new Person('Just Right', 25),
new Person('Middle Age', 50),
new Person('Very Old', 70)
];
var oldest = Person.findOldest(persons);
alert([oldest.name, oldest.age]);

Person class now has 'findOldest' method. This method is a static method. You call it by giving the name of the class: Person.findOldest.

To comment, the previous, this is just a convention. This is again just a consequence that JavaScript is really not OO language. There is nothing wrong if you define the method as:
Person.prototype.findOldest = function(persons) {
...
}

I use the first convention since:
- In the second case, every object would have findOldest, so you couldn't really distinguish what is a static method and what is not
- More typing if you follow another convention (which I do) - static methods should be called with the name of the class instead of the object instance name.

In fact, you could have noticed that '.prototype' is just the object. It is a special object, since when you say 'new Person' it will make the object and copy everything from Person's prototype object into the instance. However, with static methods, you could very well do something like this:
Person.staticMethods = {};
Person.staticMethods.findOldest = function(persons) {
...
}

Try it - works the same. I omit everything both prototype, staticMethods or whatever else you could put there. It is clear without these qualifications that this is a static method if you always follow this convention (not hard).

The same way works for static variables:
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.isAdult = function() {
return this.age >= Person.adultAge;
}

Person.adultAge = 18;

var persons = [
new Person('Very Young', 10),
new Person('Just Right', 25),
new Person('Middle Age', 50),
new Person('Very Old', 70)
];
for(var i = 0; i < persons.length; i++)
alert(persons[i].isAdult());

'adultAge' is a static variable in Person class. The above will output: false, true, true, true, since only 'Very Young' is not adult.

Hope this helped a little. In the next part, I'll write about inheritance.

32 comments:

Anonymous said...

JS doesn't have classes, it has constructors instead. A little difference :D

Unknown said...

JavaScript is a good program and very easy to use. I don´t like a complex program. I prefer javascript because i consider it like a device very eficient and it have a good quality.
I always looking for the quality that is why i prefer to buy viagra because i always have a great result in my sexual life.

pedro velasquez said...

It may be shocking news, but JavaScript is a very powerful object-based (or prototype-based, whatever you wish to call it) language.dominical costa rica tours
Yes, JavaScript is a powerful language, not just something that's handy for image rollovers and other corny, flashy effects. However, very few people who have used JavaScript realize its capabilities. If you're one of these people, this tutorial is aimed at you.
http://www.dominicalcostaricatours.com

pedro velasquez said...

OOP is a style of programming that allows you todominical costa rica tours define or manipulate your data as objects with attributes and methods applied to those objects. These objects can include features such as polymorphism, inheritance, encapsulation, modularity and more.
http://www.dominicalcostaricatours.com

Josh said...

Vimax is reliable stuff to accomplish your sexual dysfunction. It has been proven by many men to augment virility and genital.

Unknown said...

Nice post! Thanks for sharing!
Comprare Xenical

mark said...

best organic seo services
Very interesting thanks. I believe there's even more that could be on there! keep it up

Muhammad Alexander said...

Ictmentors.com is one of the best organic seo services provider When you use our service, you can rest assure that you will always get what you paid for, and this is guaranteed.


the best seo company

mark said...

Very significant article for us ,I think the representation of this article is actually superb one. This is my first visit to your site
cost effective advertising

Imran said...

Great post. i like it. feeling great when reading your post. The content of the articles there will be a lot of attractive people to appreciate
Buy sildenafil

Mohtasham said...

Man I must say your mind works regarding all the this. I learned alot from your article keep teaching us more. I really appreciate you and want to talk you please tell me how can contact you? how to cook biryani l latest sms l la fitness

mark said...

Hey great stuff, thank you for sharing this useful information and i will let know my friends as well. drug discussion
drug discussion forum
drug forum

Isabella Kaun said...

I really liked your article.

http://www.angelslimoservice.com

Mahesh said...

This is a really good read for me. Must agree that you are one of the best bloggers I ever saw. Thanks for posting this informative article.
Buy Stratterra

Anonymous said...

I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts.
wedding dresses

Silviu said...

You wrote an interesting article about Java Script OO programs.

Bubu plantarea trandafirilor Tzuppy

Imran said...

Thanks for you sharing. This kind of topic is good for people to learn more about it, and that people should be every day less ignorant..
Order Biltricide 600 mg Drugs

Imran said...

Thank you so much for sharing this post.Your views truly open my mind.
Push Up Bra

Seo Mumbai said...

Thank you for sharing this kind of important information. and especially for sharing your own experience with these.
Play Rummy

Sabra Allsbrook said...

wow...it is pretty Yes you are right here at this topic. I am agree with you here. Keep up the great job.

5 star hotels columbus ohio

Brock Kutchera said...

PORTLAND ART MUSEUM

Wooow! This is some nice work. Thanks for sharing the information! I found this article very interesting and informative! Keep sharing!

Knox Karter said...

Wow its totally a unique dress designs really very impressive..

Trade Logo

Henry Amely said...

Great blog. All posts have something to learn. Your work is very good and i appreciate you and hopping for some more informative posts.
Post free Ads in Pakistan

Unknown said...

When we read a story, we inhabit it. The covers of the book are like a roof and four walls. What is to happen next will take place within the four walls of the story.
And this is possible because the story's voice makes everything its own.
Business IT Support London

Unknown said...

Too good, recently there are few more to this article, in the heart feel very happy and the content to life, and very detailed explained the reason, in the life gives me such a big help, I very thank the authors share, I will continue to focus on, looking forward to a better.cabs in w2 | cab w2 | w2 taxis

Unknown said...

No matter how long under the rain, and eventually a rainbow; No matter how much you sad, believe that happiness in the front waiting.mirza maqbool | Maqbool mirza

Unknown said...

Very nice post. I really enjoy the article. I come here from the Google while searching for some good article. Thanks Bridal lehenga

Unknown said...

Very interesting thanks. I believe there's even more that could be on there! Keep it up.
cheap flights to africa from london heathrow

Unknown said...

No matter how many blogs, which are able to stand out, attract the line of sight of people, the article content is very wonderful, continue to come on to write this article.
SEO Expert

soniya arora said...

Mumbai Exclusive escorts is providing you high class services in the city and our featured escorts girls, Muskan is one of them, you can hire her services @ 24/7 at just a call, so never drop the chance which is offering by call girls in mumbai . Our offer is Limited. Please browse our websites given below.

mumbai call girls
mumbai escorts
mumbai escort
mumbai escorts agency
mumbai escorts service
mumbai independent escorts
Escorts service in mumbai
independent mumbai escorts

Suhana said...

Good article. Thanks for sharing lots of information. Its very helpful.Smartly does all the time.

Best Free Android Games of 2019

Danny Danials said...

Have you attempted this new app Gmail Apk : that is certainly exceptional.