Showing posts with label OO JavaScript. Show all posts
Showing posts with label OO JavaScript. Show all posts

Monday, May 14, 2012

JavaScript Object Oriented Technique #0 Common Object Methods

Whenever we define a JavaScript class, there are three methods we should immediately define.

toString()

We should be able to return a string representation useful enough for debugging purposes.

We might want to consider adding a static parse() method to our class, parsing a string output from toString() back to object form.

The usual conventions, for objects, is to surround the string by brackets [...] and describe the object's properties within it.

Polygon.prototype.toString = function() {
    return "[Polygon with perimeter "+this.perimeter+", with area "
        + this.area+", centered at ("+this.x+", "+this.y+").]";
}

valueOf()

Typically, we write an valueOf() method to give us a number form of our object.

The textbook example is, since JavaScript number objects are supposedly "real" numbers, then for a complex number object the valueOf() should return the real part. Why? Because it lets us do the following:

var foo = new Complex(1,2);
var bar = new Complex(3,4);
var spam = Complex.sum(foo,bar); // spam is the complex number (4,6)
var eggs = foo + bar; // eggs is the number 4

Also note that the valueOf() method is called when concatenating a string with your object. So continuing from the previous example:

console.log("foo = " + foo); // uses valueOf(), displays "foo = 1"
console.log("foo = " + foo.toString()); // displays "foo = {1,2}"

You have been warned!

Comparison Methods

It's useful to sort objects, and creating comparison methods allows us to do this.

The first one we should consider is equals(), which tests if two objects are equal in some sense. Usually it's if the properties are the same.

Next we need to test for inequalities. We implement a compareTo() method, which should behave as follows:

foo.compareTo(bar)>0; // foo > bar
foo.compareTo(bar)==0; // foo == bar
foo.compareTo(bar)<0; // foo < bar

I suppose the best implementation might have the following skeleton:

MyClass.prototype.compareTo = function(that) {
    if(this.equals(that))
    {
        return 0;
    }
    // else return something like "this.valueOf() - that.valueOf()"
}

Again, it depends on the circumstances...

JavaScript Object Class

JavaScript Object Oriented Framework

JavaScript is fairly quirky (you can learn it at the code academy). It is object oriented, but its a sort of duck typed version.

Every object is really an associative array, so writing foo.bar is the same as foo["bar"]. They are synonymous.

Curiously enough, JavaScript's object oriented framework has a base class called Object. Lets discuss its properties.

Object Properties

What properties does a generic object have?

1. It keeps track of its own constructor, for example:

var foo = new Array();
console.log(foo.constructor === Array); // prints "true"

The instanceof operator checks the value of the constructor property.

2. We can also convert an object to a string by a toString() method.

This does the obvious thing: returns a string representation of the object.

(Actually, if you're a mathematician, you might want to make a toTeX() method...)

3. What about converting an object to a primitive type (well, a primitive type except a string)? We have the valueOf() method.

4. Since we're duck typing objects, we might want to check the properties an object has. We can do this with the hasOwnProperty() method.

It's a function that takes a string, for example "toString", then checks to see if our object has it or not. If our beloved object has it, then foo.hasOwnProperty("toString") returns true.

5. The object base class has a method testing a given property if it's enumerable or not. In other words: it tests if we can use it in a loop construction. This method is called propertyIsEnumerable(). For example:

var foo = { bar:0 };
foo.propertyIsEnumerable("x"); // returns true
foo.propertyIsEnumerable("spam"); // returns false, since foo.spam is undefined
foo.propertyIsEnumerable("valueOf"); //returns false for inherited properties

6. The last method I'll discuss is kind of tricky. The isPrototypeOf() method is similar to the instanceof operator discussed above (see this discussion [StackExchange.com] for more details).

Object.prototype.instanceOf = function( iface )
{
    return iface.prototype.isPrototypeOf( this );
};

Addendum: to find all the properties of the Object class on YOUR system, run the following in your browser's javascript console (however you find that...on Mozilla, it's in the "Tools" part of the browser):

function getAllProperties(object){
    return Object.getOwnPropertyNames(object);
}
console.log(getAllProperties(Object));

/* prints out
[ 'prototype',
  'getPrototypeOf',
  'getOwnPropertyDescriptor',
  'keys',
  'defineProperty',
  'defineProperties',
  'create',
  'getOwnPropertyNames',
  'isExtensible',
  'preventExtensions',
  'freeze',
  'isFrozen',
  'seal',
  'isSealed',
  'length',
  'name',
  'arguments',
  'caller' ] */