User-defined Objects in JavaScript

You have already met the idea of objects in JavaScript as far back as lesson 1, and have been using objects like document on a regular basis since. Well, it won't surprise you to learn that you can define your own objects. These objects will have:

  • Properties: These are varibles associated with the object - pieces of information that "belong" to it. If the object were a dog, for example, the properties might include its breed, its age, its name etc.

  • Methods: These are functions, things that the object can do. Continuing the dog analogy, the methods might include "bark", "answer to its name" etc.

An object is defined using a function and then instances of the object are set up using new, in a similar way to dates and arrays. Take a look at this example:

<script language="JavaScript">
function dog ()
{ this.breed = "Golden Retriever";
  this.age = 10;
  this.name = "Dylan";
}

var pet = new dog();
var guidedog = new dog();

document.write("The pet's name is " + pet.name + "<br />");
document.write("The pet's breed is " + pet.breed + "<br />");

document.write("The guide dog's name is " + guidedog.name + "<br />");
document.write("The guide dog's breed is " + guidedog.breed + "<br />");

</script>

This script defines an object called dog and sets up two instances of it, pet and guidedog. You will notice that the function contains a special reference to this, which refers to the particular instance being created, so when pet is being set up, this.breed refers to pet.breed and when guidedog is being set up, this.age refers to guidedog.age etc.

Of course, the problem with the script above is that both dogs are set up with the same details. We can set up the different dogs with different names, ages and so on, by passing them as parameters:

<script language="JavaScript">
function dog (n, b, a)
{ this.breed = b;
  this.age = a;
  this.name = n;
}

var pet = new dog("Dylan", "Golden Retriever", 10);
var guidedog = new dog("Saracen", "Alsatian", 6);
</script>

This time, the parameters specify different details for each dog, so pet.name and guidedog.name produce very different strings.

Adding methods to objects

We can also add methods to objects. Here is an example using triangles as the objects created:

<script language="JavaScript">
function perimeter (side1, side2, side3)
{ return side1 + side2 + side3;
}

function what_is_type ()
{ if (this.s1 == this.s2 && this.s2 == this.s3)
    return "Equilateral";
  if (this.s1 == this.s2 || this.s1 == this.s3 || this.s2 == this.s3)
    return "Isosceles";
  return "Scalene";
}

function get_area ()
{ var p = perimeter(this.s1, this.s2, this.s3) / 2;
  return Math.sqrt(p * (p - this.s1) * (p - this.s2) * (p - this.s3));
}

function triangle (s1, s2, s3)
{ this.s1 = s1;
  this.s2 = s2;
  this.s3 = s3;
  this.type = what_is_type;
  this.area = get_area;
}

var triangle1 = new triangle(20,20,20);
var triangle2 = new triangle(40,50,50);
var triangle3 = new triangle(10,15,20);

alert(triangle1.type());
alert(triangle2.area());
</script>

Right! Now there are quite a few things that you need to notice about this. I have defined three functions, perimeter is a normal one, with three parameters - nothing special about it. It's the sort of function you met several lessons back. Functions what_is_type and get_area are a little unusual insofar as they contain references to this. Since I haven't included any parameters (although I could have) these functions will use this to get the values they need from the particular instances of triangles.

You don't really need to know what the functions do - what_is_type returns the type of the triangle (Equilateral = all three sides equal, Isosceles = only two sides equal, Scalene = all sides different), and get_area uses Hero's formula to return the triangle's area given its three sides.

Now look at the definition of the triangle object itself. The three sides (s1, s2 and s3) are set up from parameters (which I've happened to call the same names - chose to, didn't have to). Then come the two interesting lines!

I have associated the function what_is_type() with a method of the triangle object called type. I deliberately gave the method and the function on which it is based a different name, just because I could. It would probably make more sense to give them the same name.

Note the line in which the two are linked together:

this.type = what_is_type;

The function what_is_type is not followed by any brackets ()! The method it is attached to, this.type is not given any brackets either. The method is called in the main program by putting after the name of the instance and a dot, just as you would do with document.write, and this time it is given brackets, as per normal: triangle1.type().

Take a look at the function get_area which is tied to the method this.area in the same way, and called in the second alert() statement: triangle2.area().