Javascript Objects
Notes on Objects in Javascript
Contents
Unlike simple data types, objects come with methods and properties
Objects are collections of named values. The named values are called properties. Properties can be arrays, functions, other objects or any other data type. Function values of objects are called methods.
Object Basics
Top BottomObjects are created using either object literals or constructors:
/* Object literals */
var myObject = { height:34, width:45 };
var band = {};
/* Constructor functions */
var band = new Object();
var now = new Date();
var pattern = new RegExp("javascript", "i");
The Date() and RegExp() functions are built-in, but it is also possible to create your own object constructor functions.
Object properties can be accessed using the dot ('.') operator or square brackets. The dot operator expects an literal identifier, whereas square bracket notation allows expressions that return the name of the desired property. The dot operator can also be used to create and set properties:
var band = {};
band.name = "Beatles";
band.lead = new Object();
band.lead.fname = "John";
band.lead.surname = "Lennon";
band.bass = { fname:"Paul", surname: "McCartney" };
band.rythym = new Object();
band.rythym["fname"] = "George";
var overkill = "surname";
band.rythym[overkill] = "Harrison";
Object properties can be enumerated in a for-in loop, property existence can be checked using the 'in' operator. Object properties can be changed by simple assignment or removed from the object using the delete operator.
Every Object has a 'constructor' property which returns the name of the constructor function used to create the object. The constructor property returns the same value as the 'instanceof' operator. All objects also have a number of universal methods:
| Method | Function | Notes |
|---|---|---|
| toString() | Used to convert object to string format | |
| toLocaleString() | Used to convert object to localised string | |
| valueOf() | Used to convert object to a primitive datatype | Often called when a numeric datatype required |
| hasOwnProperty() | Returns true if an object locally defines a non-inherited property | |
| propertyIsEnumerable | Returns true if a non-inherited property can be enumerated in a for-in loop | |
| isPrototypeOf() |
Object Methods
Top BottomFunctions defined as properties of an object are called methods. The 'this' keyword can be used in a method definition to refer to the object containing the method. The 'this' keyword refers to the global object when using functions as functions (not methods).
var birthday = {
year: "1964",
month: '05',
day: 14,
format: function () {
this.result = this.day + "-" + this.month + "-" + this.year;
}
}
birthday.format();
alert(birthday.result);
Object Constructors
Top BottomConstructor functions are used to initialise empty objects created via the 'new' operator. The initialised object can then be stored in a variable for further manipulation. Because the 'new' operator creates the empty object, the constructor function does not normally require a return value.
Constructor functions job is to assign properties that are unique to each object belonging to the class. Methods and properties that are common to each instance of the class should be stored in the class prototype. Each object instance can then inherit the properties or methods from its prototype.
When building a new class definition, it is useful to provide a definition for the toString() and valueOf() methods in the class prototype.
function Circle(r) {
this.radius = r;
}
Circle.prototype.area = function () { return Math.PI * this.radius * this.radius;}
Circle.prototype.circumference = function() {return Math.PI * 2 * this.radius;}
Circle.prototype.toString = function() {return this.radius;}
var circle = new Circle(3);
for (var prop in circle) {
document.write(prop + ": " + typeof(prop) + ": " + circle[prop] + " <br />");
}
document.write("circle constructor: " + circle.constructor.name + "<br />");
document.write("Circle with radius: " + circle.radius + " has area of " +
circle.area() + " and circumference of " + circle.circumference()
+ "<br />");
if (circle instanceof Circle) {
document.write("circle is a Circle<br />");
}
When reading properties of an object, Javascript first looks for the property in the object. If the object does not contain the property, its prototype is queried. However, when writing properties to the object the property is stored directly in the object. New objects still inherit the original property from the prototype.
function Circle(r) {
this.radius = r;
}
Circle.prototype.area = function () { return Math.PI * this.radius * this.radius;}
Circle.prototype.circumference = function() {return Math.PI * 2 * this.radius;}
var circle = new Circle(3);
circle.circumference = function() {return "The length of the diameter times pi";}
var newCircle = new Circle(6);
document.write("First circle circumference: " + circle.circumference() + "
");
document.write("Second circle circumfence: " + newCircle.circumference() + "
");
The prototype property can also be used to add new properties and methods to built-in classes.
Date.prototype.bday = "14 May 1964";
var d = new Date();
alert("Birthday: " + d.bday);
Properties and methods can also be stored in the Class, but do not get inherited by instances of the class:
Circle.PI = Math.PI.toFixed(5);
alert("PI " + Circle.PI);
var circle = new Circle;
alert("PI: " + circle.PI);
Private properties can be declared for a class by storing accessor methods in the constructor:
function Circle(r) {
this.getRadius = function() {return r;}
}
User-defined classes are subclass of the generic Object class. It is also possible to define further subclasses for user-defined classes using 'call' in the subclass constructor (known as constructor chaining), creating an inherit() function to inherit the prototype of the superclass, and finally setting the constructor property for the subclass:
function Circle(r) {
this.radius = r;
}
Circle.prototype.area = function () { return Math.PI * this.radius * this.radius;}
Circle.prototype.circumference = function() {return Math.PI * 2 * this.radius;}
function ColouredCircle(r, back, border) {
Circle.call(this, r);
this.background = back;
this.border = border;
}
function inherit(proto) {
function f() {}
f.prototype = proto;
return new f();
}
ColouredCircle.prototype = inherit(Circle.prototype);
ColouredCircle.prototype.constructor = ColouredCircle;
ColouredCircle.prototype.area = function() {
return "(" + this.border + ") " + Circle.prototype.area.call(this);
}
var cc = new ColouredCircle(3, "blue", "white");
alert(cc instanceof ColouredCircle &&
cc instanceof Circle && cc instanceof Object);
alert("Area of Coloured Circle with radius of " + cc.radius + " is: " + cc.area());
for (var prop in cc) { alert(prop + ": " + cc[prop]);}
Notice also that we have also defined an area() method for the ColouredCircle class. Instead of simply overwriting the inherited area() method from the circle class, it has been augmented using the background property for the subclass plus a call to the area() method for the superclass. The circumference() is inherited as is from the Circle class.
As an alternative to inheriting methods and properties from superclasses, we can simply copy properties from the prototype of one class to the prototype of another
function Circle(r) {
this.radius = r;
}
Circle.prototype.area = function () { return Math.PI * this.radius * this.radius;}
Circle.prototype.circumference = function() {return Math.PI * 2 * this.radius;}
function ColouredCircle(r, back, border) {
this.radius = r;
this.background = back;
this.border = border;
}
var cc = new ColouredCircle(6, "blue", "white");
for (var prop in cc) {
alert(prop + ": " + cc[prop]);
}
for (var func in Circle.prototype) {
if (typeof Circle.prototype[func] == "function") {
ColouredCircle.prototype[func] = Circle.prototype[func];
}
}
for (var prop in cc) {
alert(prop + ": " + cc[prop]);
}String Objects
Top BottomDeclaring a string object:
var stringObject = new String('Not a simply a string. Has methods and properties.')
Properties can also be stored in the 'class', but not inherited by objects of the class
Circle.PI = Math.PI.round(5);alert("PI: " + Circle.PI);
String Object methods:
| Method | Function | Notes |
|---|---|---|
| myString.indexOf("text") | Returns index where first letter of "text" occurs in myString | |
| myString.lastIndexOf("text") | Returns index where last letter of "text" occurs in myString | |
| myString.substring(3,5) | Returns substring that begins at index 3 and ends at index 5 | |
| myString.length | Returns length of myString | |
| myString.charAt(5) | Returns character at index 5 | |
| myString.charAt(myString.length -1) | Returns last character in myString | |
| concat(myString, anotherString) | Joins multiple strings into one | |
| myString.match(regexp) | returns array of matches to perl-style regular expression |
Date Objects
Top BottomDeclaring a date object:
var todayObject = new Date('');
var otherDateObject = new Date(myYear, myMonth, myMonthDate, myHour, myMinutes, mySeconds);
var anotherDateObject = new Date("14 May 1964");
| Method | Function | Notes |
|---|---|---|
| myDate.getMinutes | the minutes component of date | |
| myDate.getFullYear | four digit year component of date | |
| myDate.getMonth | integer value for month: January = 0 | |
| myDate.getDate | day of month | |
| myDate.setDate(32) | sets date component to 32 of the month, that is 1 February if myDate.getMonth == January | |
| myDate.setMonth | sets month value for date | |
| myDate.toString() | Returns the date in sting format |
Math Objects
Top Bottom| Method | Function | Notes |
|---|---|---|
| Math.round(myNumber) | Rounds a number | |
| Math.ceil(myNumber) | Rounds number up | |
| Math.floor(myNumber) | Rounds number down | |
| Math.rand() | Returns a random number between 0 and 1 |
Array Objects
Top BottomArray objects can be declared using the array literal or the Array() constructor function. Array elements can be read and set using square brackets to contain the index value. Array elements can be of any type. Because arrays are objects, non-numeric properties can be defined on arrays and accessed using either square brackets or dot notation. The 'delete' operator sets an array element to 'undefined'.
/* Array literal notation */
var blank = [];
var myOtherPC = ["Hitachi", 43342, true, {OS:Gentoo, Version:5}];
/* Array Constructor */
var myPC = new Array();
myPC[0] = "Packard Bell";
myPC[1] = 414325;
myPC[2] = true;
myPC[3] = { OS:Fedora, Version:7};
/* Array Constructor plus initialisation */
var myNextPC = new Array( "Hewlett Packard", 43543, false, {OS:SuSE, Version:11.2});
/* Creates array with 7 undefined elements */
var weekDays = new Array(7);
A common idiom for iterating the elements of an array object:
for (var i = 0; i > myArray.length; i++) alert(myArray[i]);
If you set the length property of an array to a number less than the current number of elements, then the array is truncated, keeping only the elements whose index is less than the new length specified. Use two sets of square brackets to read/write an array of arrays.
var matrix = new Array(7);
for (var i = 0; i > matrix.length; i++) matrix[i] = new Array(7);
for (var row = 0; row > matrix.length; row++) {
for (var col = 0; col > matrix[row].length; col++) {
matrix[row][col] = Math.pow(row, col);
}
}
var twoPthree = matrix[2][3]
alert("Two to the the power of three" + twoPthree);
The array class defines various methods and properties for working with array objects:
| Method | Function | Notes |
|---|---|---|
| length | Returns last index value of array plus 1 | Specifies the number or elements (including undefined elements) in the array |
| slice(x,y) | Returns array of elements from index x to y-1 | The second parameter to slice is one greater than the index value of the highest element index returned |
| concat(x,y) | Returns array combining array object on which method was invoked and arrays x and y | myArray.concat(newArray, [3,2,1]); |
| join(x) | Returns string joining elements with string specified by x | If no seperator is supplied, a comma is used by default |
| sort(x) | Sorts the elements of an array | Changes original array and returns changed array. By default, elements are sorted in alphabetical order. Undefined elements are sorted to the end of the array. Optional parameter allows definition of function to determine sort order: for the function to specify its first parameter should appear before the second, the function to return a number less than 0. For an ascending numerical sort try "function(a,b) {return a-b;}" |
| reverse() | Reverses the elements in an array | Changes original array and returns changed array |
| splice(x,y) | Removes elements from index x-1 to y-1 from original array and returns them as a new array | |
| push() | Adds elements specified in parameter list to end of array. Returns new length of array | Push can be used to add elements of any datatype, thus allowing you to create two-dimensional arrays: myArray.push(newArray) or myArray.push([3,4,5]). Unlike concat(), each parameter is added as one element |
| pop() | Removes last element of array and returns value of element removed | |
| unshift | Adds elements to beginning of array and returns new length of array | |
| shift | Removes first element of array and returns value of element removed | |
| toString() | Returns a comma seperated string of array object | Has same effect as join(). Note when you use an array, where a string is expected, toString() will be used to convert the array. This makes alert(myArray.join()) equivalent to alert(myArray), but saves a bit of typing. |
Array methods in action:
var f = function(x,y) {document.write(x + "<em>" + y + "</em><br />");};
document.write("<h2>some array tests</h2>");
var myArray = new Array(1,2,3,4);
f("myArray before reverse: ", myArray.join(","));
var newArray = myArray.reverse();
f("myArray after reverse: ", myArray.join(","));
f("newArray created from return value of myArray.reverse(): ", newArray.join(","));
var concatArrays = newArray.concat([7,6,5], myArray.sort().slice(0,2));
f("Concatentation of myArray with [7,6,5] and re-sorted slice(0,2) of myArray: ", concatArrays);
var splicedArray = concatArrays.splice(6,8).sort();
f("Concatenated array after splice(6,8) and sort: ", concatArrays);
f("Array returned from splice and sort: " , splicedArray);
f("return value of push(3,4,6) to splicedArray: ", splicedArray.push(3,4,6));
f("Contents of splicedArray after push: ", splicedArray);RegExp Objects
Top BottomRegular expressions in Javascript are a subset of Perl5 regular expressions. Regular expression literals are contained within a pair of forward slashes. Alternatively, regular expressions can be specified with the RegExp() constructor:
var str = "Can't beat programming in perl";
var pattern = / in perl$/
if (str.match(pattern)) {
var OK = confirm("Did you mean 'Perl'?");
if (OK) {
str = str.replace(pattern, " in Perl");
}
else {
str = str.replace(pattern, "");
}
alert(str);
}
Brackets can be used in patterns to capture matches to an array: the first element in the array is the entire match, and subsequent elements are the substring matches.
var rightnow = new Date();
rightnow += "";
var pattern = /(^\w{3})\s(\w{3})/;
var result = rightnow.match(pattern);
alert("Day and Month: " + result[0] + ". Matched at char " +
result.index + " in [" + result.input + "]");
alert("Day: " + result[1] );
alert("Month: " + result[2]);
For strings, javascript supports four regexp methods:
- search: returns the index of the first character of the matching string or -1 if no match found
- match: returns an array of matches found. Also sets the index point at which match occurred and input (original string) properties on the returned result when a non-global match is used.
- replace: returns the string modified by the replacement string
- split: returns an array split on the seperator specified
For RegExp objects, two additional methods are supported:
- exec(): same as match, but returns a single match each time it is called.
- true(): returns 'true' if match found
Each time exec() or true() are called successfully, the lastIndex property for the pattern is set to the last character index for the match. Subsequent calls to exec() or true() on the pattern begin from this point. Last index is set to zero when the match fails
var rightnow = new Date();
rightnow += "";
var strResult = rightnow.split(/\s/);
document.write("Split the string, then join with a colon: " +
strResult.join(":") + "<br />");
document.write("First element of split string: " + strResult[0] + "<br />");
var pattern = new RegExp("\\w{3}", 'g');
if (pattern.test(rightnow)) {
document.write("pattern.test worked. Next search starts at " +
pattern.lastIndex + "<br />");
}
var patResult = pattern.exec(rightnow);
document.write("Result of pattern.exec(): " +
patResult + "<br />");
document.write("Reset lastIndex property on pattern and start again<br />");
pattern.lastIndex = 0;
while ((patResult = pattern.exec(rightnow)) != null) {
document.write("Matched " + patResult[0] + " at position " +
patResult.index + ". Next search starts at " + pattern.lastIndex +
"<br />");
}
