JavaScript/Simple OOP

From Spherical
Revision as of 00:18, 14 June 2013 by Apollolux (talk | contribs) (link text)
Jump to: navigation, search

There is an alternate article for this that is more thorough, but uses more jargon and is probably more suited to more advanced programmers. This more advanced article covers advanced concepts such as Polymorphism and Inheritance. See Object oriented programming.

So you heard a lot about OOP and decided to check it out? Good, that's why we're here. I'm assuming you know a bit about JavaScript syntax, but this shouldn't be too hard, just things like if and function.

If you want to learn, but don't want to shovel through text, go to I'm dumb...

If you know a bit about classes but don't like explanations, go to I'm lazy...

If you want the whole explanations thing, as well as two ways to define methods, just read through the example.

What is OOP?

OOP = Object-oriented programming

It's using these things called objects to do stuff. An object is just like a car, or a ball, or a person. It has properties: info that describes it, e.g.

person.hairColour = CreateColor(0, 0, 0); // black hair

Objects also have methods: things that the object can do, e.g.

person.jump(5);

Why should I care about OOP?

Two reasons. First, it's a very natural way of looking at things. It helps a lot in games, because objects occur very naturally in them too, like the player, a spaceship, a sword, shield, an enemy, and so on. Sphere makes games.

Second, it makes your JavaScript code much neater and easier to handle later on. OOP stops you repeating code and so lets you type less. Less typing = less errors = faster completion of your game. It grows easier too.

I'm dumb...

This is speed mode. From zero to hero in ten minutes.

Objects are like things in the real world. Things have properties, e.g. person has an eyeColor, and they have methods, e.g. person can clap.

Here's how we can make a simple Person object:

function Person(name, eyeColor) {
  this.name = name;
  this.eyeColor = eyeColor;
}

We can now make Persons:

var bob = new Person("Bob", "blue");
var ted = new Person("Ted", "teal");

We can get properties:

var a = bob.name     // a now contains "Bob"
var b = ted.eyeColor // b now contains "teal"

We can set properties:

bob.eyeColor == "brown"  // false
bob.eyeColor = "brown";
bob.eyeColor == "brown"  // true

We can make methods. They're like functions, but for an object:

Person.prototype.clap = function () {
  Abort(
      "This was a silence game.\n" +
      "You just lost, " + this.name + ".\n" +
      "Game over.\n" );
}

We can now call methods.

ted.clap();

That will show:

This was a silence game.
You just lost, Ted.
Game over.

That's it!

Example: kicking people

The choice might be my misanthropy showing. Oh well.

In this example, we'll make a MalePerson object, capable of kicking, and being kicked.

The MalePerson template

Let's write some code:

function MalePerson(name) {
  this.name = name;
  this.maxHitPoints = 20;
  this.hitPoints = this.maxHitPoints;
}

This is like a template for all MalePersons. They all have a name, they all have maxHitPoints and they all have hitPoints. Those are all called properties.

Objects that come out of the same template can have different properties, e.g. one MalePerson object could have a name of "Bob", while another has a name of "Jim". You'll see this when we make a few objects from this template.

MalePerson methods

Methods are a way for your objects to 'do' things, like 'kick' or 'takeDamage'. They're just functions, but connected to an object.

There are 3 ways of making methods. I'll only cover one.

/**
 * Kick another MalePerson.
 * @param  victim  The other MalePerson object.
 * @param  location  String, place on body to kick the other person.
 */
MalePerson.prototype.kick = function (victim, location) {
  victim.takeDamage(location, 11);
}

/**
 * Take damage to an area.
 * @param  area  String, the location of the damage.
 * @param  amount  Number, normal amount of damage taken.
 */
MalePerson.prototype.takeDamage = function (location, amount) {
  if (location == "groin")
    this.hitPoints = this.hitPoints - amount * 2;
  else
    this.hitPoints = this.hitPoints - amount;
}

That stuff in /* */ is just for people like you and me. JavaScript ignores them, so you can put whatever in them, or leave them out if you want.

Notice the use of prototype, along with function. This way, all MalePerson objects will gain the kick and takeDamage methods. See how methods are set as functions?

Making objects

That's all fine and well, we've prepared a template. But by itself, a template doesn't do anything. How do we use the template? Easy, just watch and learn.

Let's make a couple of MalePersons:

var timmy = new MalePerson("Timmy");
var thug = new MalePerson("Greasy Thug");

This how we make new MalePerson objects. Get it? :)

Each object is distinct, just like one ball in real life is different from another. Going with the above two lines, see if you can figure out these:

timmy.name == "Timmy"       // true
thug.name == "Greasy Thug"  // true
timmy.name == thug.name     // false
timmy.name != thug.name     // true

Yep, these guys have different names. This is how we get properties from objects.

Using objects

Now let's make our MalePersons again, and one will kick the other.

// These two lines were from above.
var timmy = new MalePerson("Timmy");
var thug = new MalePerson("Greasy Thug");

thug.kick(timmy, "thigh");

Abort(
    timmy.hitPoints + "HP left for Timmy\n" +
    thug.hitPoints + "HP left for Greasy Thug.\n" );

Okay, poor Timmy has just been kicked by our Greasy Thug. This is the output:

9HP left for Timmy
20HP left for Greasy Thug

The first bold line is where the Greasy Thug kicked Timmy.

The second bold bit is how we access Timmy's hitPoints property, showing how hurt he is.

The third bold bit is how we access the Greasy Thug's hitPoints property. He hasn't been hurt a bit.

Can you figure out how to display the names on the last lines like the hitPoints as well, instead of directly typing "Timmy" and "Greasy Thug"?

Bringing it together

Let's put this all together, shall we? The big method comments have been left out for readability.

function MalePerson(name) {
  this.name = name;
  this.maxHitPoints = 20;
  this.hitPoints = this.maxHitPoints;
}

MalePerson.prototype.kick = function (victim, location) {
  victim.takeDamage(location, 11);
}

MalePerson.prototype.takeDamage = function (location, amount) {
  if (location == "groin")
    this.hitPoints = this.hitPoints - amount * 2;
  else
    this.hitPoints = this.hitPoints - amount;
}

Now let's give Timmy a chance for revenge:

var timmy = new MalePerson("Timmy");
var thug = new MalePerson("Greasy Thug");

timmy.kick(thug, "groin");

Abort(thug.HitPoints);  // Shows -2

Uh oh, Timmy better do some fast running: he just killed the thug.

What did I just learn?

Here's the lingo, if you've heard about classes before:

  • objects (new ObjectName())
  • properties (with this.blah)
  • methods (obj.kick())

And don't kick MalePersons in the groin. It hurts.

I'm ambitious!

Advanced OOP in JavaScript covers inheritance, e.g. using a Person function to make MalePerson and FemalePerson, superclasses (Person) and subclasses (MalePerson and FemalePerson), getters and setters, as well as saving code using polymorphism, and a trick to allow calling superclass methods from the subclasses.

I'm lazy...

The example was big, so here's the cheat sheet.

function MyObjectName(param1, param2) {
  // Properties
  this.property1 = param1;
  this.property2 = param2;
}

// Methods
MyObjectName.prototype.method1 = function () {
  // Code for method1
}

MyObjectName.prototype.method2 = function () {
  // Code for method2
}
// Making objects
var object = new MyObjectName(12, "blah");
var object2 = new MyObjectName(11, "haha");

// Using object properties
if (object.property2 == "blah")
  object.property2 = "blah was lame anyway";

// Using object methods
object.method1();
object2.method2(3);

Cheers! --Tunginobi 10:22, 28 January 2007 (GMT)