The traditional “first program” for a new language is the lowly “Hello, World!”. A “Hello, World!” program just runs and says “Hello”! Its purpose is to provide a simple way to illustrate and use the fundamental elements of a language.
For an Object-Oriented Programming Language (OOPL), such as JavaScript, “Hello, World!” can require designing a new class. (Even if not required, it's reasonable to design a new class as part of demonstrating any new OOPL.)
The standard “Hello, World!” class is the X,Y point class (such as might be used for graphs or any graphic software).
An XY Point class makes a good example, because it can be as simple–or as complicated–as the example requires. On this page, we'll start with a very simple example and progress to increasingly more complex examples. Each new version adds useful capabilities to the class.
We start where the last page left off: with a Point() constructor function we use to create new Point objects. That version of the Point constructor takes x and y arguments used to initialize the x and y members.
function
Point(x,y) {this
.x = x;this
.y = y; }
The first improvement allows us to create new instances with none, one or both initialization arguments. New Points with no arguments set x and y to 0 (zero). New Points with one argument set both x and y set to the argument value. New Points with both arguments set x and y appropriately.
function
Point(x,y) {this
.x = (x ==undefined
? 0: x);this
.y = (y ==undefined
?this
.x: y); }
This version uses the ?:
expression to check the argument and return an appropriate value.
Arguments are only defined if the caller passes a value,
so the expression compares an argument to the JavaScript keyword, undefined
.
The value for the new property comes from the argument, only if the argument is passed.
Otherwise, it's assigned a default value.
The x member has a default value of 0 (zero). The default value for the y member is the x member's value. If the x defaults to zero, then so does the y member. If the x has a value, then that value is the y default value. The end result is that initializing no members results in setting both to zero. Initializing only x sets both members to that initial value, and initializing both set them to separate values.
NOTE: You could just as easily design Points where the y default is always 0.
The code fragment below shows the creation of four new Point
objects.
It also shows one way we might print the values of these objects.
(Note the assumption of a Print()
function.)
var
p1 =new
Point();var
p2 =new
Point(10);var
p3 =new
Point(21,0);var
p4 =new
Point(21,42); Print('p1=',p1.x,',',p1.y); Print('p1=',p2.x,',',p2.y); Print('p1=',p3.x,',',p3.y); Print('p1=',p4.x,',',p4.y);
When run, the output is:
p1=0,0 p2=10,10 p3=21,0 p4=21,42
The next version adds methods to the Point class.
In this version, we define standalone functions as methods and bind references to those functions to new object instances.
The methods, like the object constructor function, use this
to access the object attributes.
We add two methods: Reset and Move. The first method resets the point to 0,0 (origin) coordinates. The second takes two arguments as new x,y coordinates.
function
Point(x,y) {this
.x = (x ==undefined
? 0: x);this
.y = (y ==undefined
?this
.x: y);this
.Reset = Point_Reset;this
.Move = Point_Move; }function
Point_Reset() {this
.x = 0;this
.y = 0; }function
Point_Move(x,y) {this
.x = x;this
.y = y; }
The code fragment below starts with the creation of a new Point
object.
It Print()s that value, Reset()s the Point and then Print()s it again.
Last it Move()s the Point and Print()s its final value.
var
p1 =new
Point(21,42); Print('p1=',p1.x,',',p1.y); p1.Reset(); Print('p1=',p1.x,',',p1.y); p1.Move(100,100); Print('p1=',p1.x,',',p1.y);
When run, the output is:
p1=21,42 p1=0,0 p1=100,100
The next version moves the separate method functions into the object constructor function. The end result is the same, we just don't have to worry about making up names for the functions or having them get accidentally separated.
function
Point(x,y) {this
.x = (x ==undefined
? 0: x);this
.y = (y ==undefined
?this
.x: y);this
.Reset =function
() {this
.x = 0;this
.y = 0; }this
.Move =function
(x,y) {this
.x = x;this
.y = y; } }
Because the change in this version is internal, we'd use it exactly the same as we'd use the previous version (so there's no usage code fragment).
Our final version for this round adds a finishing touch: a nicer way to print the x,y values. Not only does this provide a cleaner way to print the object, it provides a traditional JavaScript way.
All JavaScript objects inherit a method, toString()
, that returns a String
representation of the object.
JavaScript calls this method any time it wants to print an object.
If you override toString()
, you override the default print behavior of the object.
All that's required is providing a method, named toString()
.
function
Point(x,y) {this
.x = (x ==undefined
? 0: x);this
.y = (y ==undefined
?this
.x: y);this
.Reset =function
() {this
.x = 0;this
.y = 0; }this
.Move =function
(x,y) {this
.x = x;this
.y = y; }this
.toString =function
() {return
'Point:x,y=' +this
.x + ',' +this
.y; } }
The code fragment below creates two objects and Print()s them.
var
p1 =new
Point(10,10);var
p2 =new
Point(19,21); Print(p1); Print(p2); p1.Move(100,100); p2.Reset(); Print(p1); Print(p2);
When run, the output is:
Point:x,y=10,10 Point:x,y=19,21 Point:x,y=100,100 Point:x,y=0,0
(back) | § | Top | Web | JavaScript | Tutorial |
---|