01219245/javascript1/tutorial4

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
This is part of 01219245.

Everyone should know what Hangman Game is. If you don't, it's a simple vocabulary game and you can try it here.

Task breakdown

Exercise: Let's think about what our Hangman program has do to.

Expand this box to see a few examples after you finish thinking.

  • Random a word.
  • Show the word with blanks.
  • Read the guess alphabets and show the correct ones in the word.
  • Count the number of wrong guesses.
  • Show the hangman figures.
  • Show a list of alphabets from which the user can choose.
  • Hide used alphabets.
  • Reset the game after the game ends.
  • (... I can keep listing other features.)

Not all features above are extremely important to the game. For example, if you don't even draw the hangman figures, the game will be a pretty weird hangman game, but it is still the hangman game. If we can only choose 2 features to implement, we can simply throw away the hangman drawing task.

Exercise: From the list above, try to order the items according to their importance to the game.

Expand this box to see some possible ordering.

This is how I would order it. It is OK if your preference is different.

  • Show the word with blanks.
  • Read the guess alphabets and show the correct ones in the word.
  • Count the number of wrong guesses.
  • Random a word.
  • Show the hangman figures.
  • Show a list of alphabets from which the user can choose.
  • Hide used alphabets.
  • Reset the game after the game ends.

Core mechanics

Notice that the first few most important features are related to game mechanics. Let's try to think about that part, i.e., what is the essence of the game?

To see that, let's try to think about a sample play between A and B:

  • A: I have this word _ _ _ _ _.
  • B: A?
  • A: No, I don't have A. This is your first wrong guess.
  • B: E?
  • A: Yes I have E. The word is now: _ E _ _ _.
  • B: I?
  • A: No, I don't have I. This is your second wrong guess.
  • B: O?
  • A: Yes I have O. The word is now: _ E _ _ O.

What do we see here? Do you see any data? Do you see any "behavior" or "operations with data"? This is a nice indicator that we can group the data and functions related to this piece of data into an object.

Let's call it, for now, a hangman word and think about the operations we would like to perform with it.

Hangman word:

  • We want to check if the word contains an alphabet.
  • We want to get hints (e.g., something like "_ E _ _ O")

To do so, we should create the hangman word object with the "hidden word", i.e., hangman word should know the word to guess.

With this in mind, we can think about the object's interface, i.e., how we should interact with the object. Let's think about this in a code example.

  var hangman = new HangmanWord( 'ELEPHANT' );       // how a new object is created.
  
  // Sample interaction in the JavaScript console
  hangman.getHint()                  // --> "_ _ _ _ _ _ _ _"
  hangman.check( 'Z' )               // --> false
  hangman.check( 'A' )               // --> true
  hangman.getHint()                  // --> "_ _ _ _ _ _ _ _"
  hangman.add( 'A' );
  hangman.getHint()                  // --> "_ _ _ _ _ A _ _"
  hangman.check( 'E' )               // --> true
  hangman.add( 'E' );
  hangman.getHint()                  // --> "E _ E _ _ A _ _"

More on JavaScript objects

In the previous example, we create an object using object literal notation. That syntax is very easy to use, but it is hard to create many objects of the same kind using that syntax. In JavaScript, although it is a prototype language, we can define a new class using function. Let's start by an example.

Previously if we want a dog object, we can do the following.

var dog = {
    age: 10,
    color: "black"
};

If we want to have many objects that look like this dog, we can write a function to initialize a object for us as follows.

function initDog( dog, a, c ) {
    dog.age = a;
    dog.color = c;
}

// new dogs
var dang = {};
var dum = {}
initDog( dang, 5, 'red' );
initDog( dum, 7, 'blue' );

Since creating and initializing objects are common things people want to do, the JavaScript language designers has provide a simpler syntax to do that. The idea is very similar to the above example.

To create a class, we define a constructor function for the class. This is pretty much the function initDog above.

function Dog( age, color ) {
    this.age = a;
    this.color = c;
}

We will not use this function like a normal function. To create an object, we use the new statement. It is like we call the function, but with an additional keyword new.

// new dogs
var dang = new Dog( 5, 'red' );
var dum = new Dog( 7, 'blue' );

NOTES: Don't forget the new keyword.

Adding methods

We can add a method to the object in the constructor function like this:

function sayhifunction() {
    alert( "I am " + this.age );
}
function Dog( age, color ) {
    this.age = age;
    this.color = color;
    this.sayhi = sayhifunction;
}
//----------
var dang = new Dog( 5, 'red' );
dang.sayhi();

The constructor above assigns a function to the object's property sayhi. I.e., every object of class Dog has a property sayhi which is that function sayhifunction. (I intentionally name that function sayhifunction so that it is different than sayhi.)

Note that in this case, we have to define function sayhifunction and we might pollute the name space in our program. There is another way to add a method to a class. It is through the class's prototype.

Let's add method walk to Dog's prototype:

Dog.prototype.walk = function() { alert( "I am walking." ); }

//-----
dang.walk();            // now every object knows how to walk.

When you define a function, there is also a property of the function called prototype. This is a "prototype" object where every object in the class would look for when it does not know how to perform any task. The following figure shows the objects and its prototype.

Jsproto.png

Class pattern

The following is a sample class Dog that we have written. To write a new class, you can try following this pattern.

<syntaxhighligh lang="javascript"> function sayhi() {

   // ... do something

}

function Dog( age, color ) {

   this.age = age;
   this.color = color;
   this.sayhi = sayhi;       // assign methods to the class instance in the constructor

}

Dog.prototype.walk = function() { // assign methods to the class's prototype

   // ... do something

}; </syntaxhighlight>

Assets