Javascript object like a sir

In this post I will introduce Javascript objects, how to define them, how to add attributes and methods and how to access them. Maybe you have heard that Javascript is an object oriented language but that definition is not very precise, specially when comparing to other languages. There are no classes! (and it is considered a prototypal object oriented language). Anyway now we will dip our toes into the waters just a little to become familiar with the notation. Prototypes, inheritance and other advance stuff will come next.

Creating an object

Did you read well? We are creating an object, not a class. Hey, this looks like a JSON String. You know what? JSON stands for JavaScript Object Notation, it has nothing to do with the argonauts or that amiable chap of Camp Crystal Lake. Basically you put key-value pairs inside curly brackets, where values can be any kind of js data: number, boolean, string, arrays, functions or even objects

// One single object
var oneUser = {
  login : 'falken',
  password : 'josua'
};

typeof oneUser;

otherUser = oneUser;

otherUser.login = 'root';
// Other way to access property
oneUser['password'] = '1234';

// The reference to the same!
console.log('One: ')
console.log(oneUser);
console.log('Other: ');
console.log(otherUser);

Object { login="root",  password="1234"}
Object { login="root",  password="1234"}

As you can see both oneUser and otherUser variables hold a reference to the same object.

Keys with quotes or not

We can leave out quotes, unless we want to use a key with special charactes, blank spaces, etc.. In the next example we can see how to reach attributes in two different ways and how to deal with nested objects.

var oneCustomer = {
  name : 'John Doe',
  'Customer address' : 'c/ unknown',
  '-+-+-+' : 'wtf',
  payment : { ptype : 'Visa',
             card  : '33442324234',
             'expiry date' : 'never'
            }
};

console.log(oneCustomer);

oneCustomer['name'] = '';
oneCustomer['-+-+-+'] = 'Something';
oneCustomer.payment['ptype'] = 'Account';
oneCustomer['payment'].card = '666';
oneCustomer['payment']['expiry date'] = 0;

console.log(oneCustomer);

Functions as data

Ok, if we want these objects to behave as objects in other languages, we should add some code to them. Easy peasy.

var student = {
  id : 2,
  name : 'John Doe',
  sayHello : function () {
              return 'Hello';
            }
}

console.log(student);
console.log(student.sayHello());

Hello

By now maybe you have realized that Javascript hashtables are in fact objects

Adding more properties and methods

Why not? Javascript is interpreted and weakly typed. But don't get confused. We are still playing with objects, not with classes. When we want to extend attributes of functions to a class we can use prototype (not covered yet).

...
// Adding new properties and methods:
student.age = 28;
student.sayGoodbye = function () { return 'bye';};

console.log(student.sayGoodbye());
bye

this

The well-known this is available too in Javascript. It refers current object. It comes in handy when we need to refer to our own properties in the object functions.

This operator referes to current object

var invoice = {
  description : 'Sample invoice',
    price:100.0,
    vat: 5.0,
  subtotal : function () {
              return this.price;
            },
  total : function () {
              return this.price + ((this.price * this.vat)/100);
            }
}

console.log(invoice);
console.log(invoice.total());

Constructors

Ok, we have been playing around with single instances, but what if we want to create different instances of the same kind of object. There is no class keyword, but we can define a constructor function and the call it using new reserved word to create a fresh new instance.

The next example shows a class of a kind in Javascript. It is a function with the name starting with uppercase (a convention to make it clear that this is not an ordinary function but a constructor), and inside we just add attributes and functions.

/**
* constructor for Web objects
*/
function Web () {
  this.url = 'http://localhost';
  this.name = 'Localhost';
  this.showInfo = function () {
    return this.url + ': ' + this.name;
    }
}

var oneWeb = new Web();
oneWeb.url = 'http://pello.io';
oneWeb.name = 'Home sweet home';

console.log(oneWeb);
console.log(oneWeb.showInfo());

var otherWeb = new Web();
otherWeb.url = 'http://www.elmundo.es';
otherWeb.name = 'El Mundo';

console.log(otherWeb);
console.log(otherWeb.showInfo());

Calling this function with new will create different instances.

Constructor with arguments

Being a function, adding arguments to the constructor is pretty straightforward.

/**
* constructor for Web objects
*/
function Web (url, name) {
  this.url = url;
  this.name = name;
  this.showInfo = function () {
    return this.url + ': ' + this.name;
    }
}

var oneWeb = new Web('http://pello.io','Home sweet home');

console.log(oneWeb);
console.log(oneWeb.showInfo());

var otherWeb = new Web('http://www.elmundo.es','El Mundo');

console.log(otherWeb);
console.log(otherWeb.showInfo());

constructor property and instanceof operator

Every object has at least a constructor property that we can check. Also, we can check if an object is an instance of certain type. I'm reluctant to say class.

typeof oneWeb;
"object"

oneWeb.constructor;
Web(url, name)

// Instance of operator
if (oneWeb instanceof Web) {
    console.log('Instance of Web');
}

Factory

Do you prefer factories to create instances? just create a function that returns an object.

function factory (title,text) {
  return {
    title : title,
    text : text,
    show: function () {
              return title + ': ' + text;
           }
  };
}

var comment = factory('sample','bla bla');
var comment2 = factory('sample2','bla2 bla2');
var comment3 = factory('sample2','bla2 bla2');

comment.title = 'Other';
console.log(comment);
console.log(comment.show());

console.log(comment2);
console.log(comment2.show());

Equality

Are two object equals? Not at all, the equality refers to be the same reference, that is, to point to the same object.

// Both of these are not equals
if (comment2 == comment3) {
    console.log('Are equals ==');
} else {
    console.log('Are not equals ==');
}
Are not equals ==

if (comment2 === comment3) {
    console.log('Are equals ===');
} else {
    console.log('Are not equals ===');
}
Are not equals ===

Now by reference turns out to be... true

var comment4 = comment3;

if (comment3 == comment4) {
    console.log('Are equals ==');
} else {
    console.log('Are not equals ==');
}
Are equals ==
if (comment3 === comment4) {
    console.log('Are equals ===');
} else {
    console.log('Are not equals ===');
}
Are equals ===

That's all for today. Object oriented Javascript is a hard road at first, but the payoff is worth it. Or so they say, greetz ;)