JavaScript Arrays: Properties and Methods
JavaScript Arrays - Properties and Methods
Browser/JavaScript Version | Created By |
Nav4/JavaScript 1.2 |
|
IE4/JScript 3.0 |
|
IE5/JScript 5.0 |
|
IE5.5 / JScript 5.5 |
|
Nav6/JavaScript 1.5 |
|
ECMAScript 1st edition |
|
ECMAScript 3rd edition |
|
Description
Arrays, simply put, are objects that can have a series of properties ordered
by an index number. Sometimes it matters to have a specific order to these
properties, called elements of the array. Sometimes it does not, except to give
you a grouping of common elements. (Do not confuse these elements with HTML
elements, discussed in Part III, "Document Object Model for HTML
Documents.")
Arrays are among the most useful features in JavaScript, simply for their
flexibility. In the preceding two chapters, you saw a few examples of them. You
will continue to see arrays throughout this book, in many of the examples. You
will also see a few properties within this book that are special instances of
Array(), as generated from strings and regular expressions.
Numbered and Unnumbered Properties of Arrays
Suppose you have an object myArray which is an array. Elements of
the myArray object, the numbered properties, you can reach by referring
to myArray[x], where x is the index number of the array
indicating which element you want to reach.
(Only nonnegative integers less than 232 - 1 qualify as index
numbers for an array's elements.)
The first element of myArray is myArray[0]. The second is
myArray[1]. The nth array element is myArray[n-1].
This is true for all arrays: they begin their element list at 0. The element
list for myArray is the collection of all numbered elements, from
myArray[0] to myArray[myArray.length-1]. The element list for
any array object is defined similarly.
You can always add members to an array's element list. The most common
way to do so is to refer to the length property of the array as an
element list index number. (The length property, as I will note later
in this chapter, is tied to the number of elements in the array; changes to one
will reflect in the other.) For example:
myFunc = new Array()
// myFunc.length == 0
myFunc[myFunc.length] = new Object() // myFunc[0] is now an object
// myFunc.length == 1
myFunc[myFunc.length] = new Object() // myFunc[1] is now an object
// myFunc.length == 2
This assigns a value to myFunc[x] for a
particular x (in the previous example, x =
myFunc.length). At the same time, it extends the length of the array.
Although all elements of the array are properties of the array, not all
properties of the array are elements of the array. You can add properties to an
array that will not show up in the array's element list. For instance, you
can add a method to any array much like you would add a method to other
objects:
myArray.myMethod = myFunc
myArray will have the myMethod property, but it will not be
between myArray[0] and myArray[myArray.length-1] unless you
specifically add it as a member of the element list.
You cannot refer directly to an element's index number:
alert(myArray.0) // throws exception
This can get a bit confusing when you see an error message like this in IE:
myArray.0.constructor is not an object. A numbered property like this
is always an array's index number. Netscape's error message is
clearer: myArray[0] has no properties.
An Array's Elements Can Be Any Object or Value
A new array begins only with the elements explicitly defined in the
constructor or literal notation. You can assign to every element of the array
whatever object or literal you wish. This includes objects, numbers,
strings...whatever you want.
A common practice among JavaScripters is to create two-dimensional arrays by
creating arrays as elements of a parent array:
myArray = new Array()
myArray[0] = new Array()
myArray[0][0] = new Object()
myArray[0][1] = new Object()
// ...
I have come up with a number of uses for arrays. One of them is the emulation
of java.math.BigDecimal() objects, mentioned briefly in the preceding
chapter. Each BigDecimal() object as I implement has an array of
four-digit numbers, with an optional minus sign and a mandatory decimal point
somewhere in the array's element list, which I designate as properties. By
attaching various methods for comparison and arithmetic, I make it possible for
JavaScript to handle numbers with any length of digits. (The script and its
mathematics are beyond the scope of this book.)
Another use, featured as the example at the end of this chapter, is an
extensible version of the switch statement, which is covered in Chapter
11, "The Global Object and Statements." By "extensible," I
mean a developer can add cases to the switch at will. A similar concept allows
developers to implement an emulation of method overloading, an advanced concept
I covered in a limited fashion as the example in Chapter 2,
"Function()." Still another use of arrays is my Basket of Windows
script, which I feature as the example in Chapter 15, "window."
Populating an Array Automatically
You can define a few elements in the array (populate the array) as you define
the array. The first way is to include the elements as arguments in the
Array() constructor:
var myArray = new Array("red", "green", "blue")
This makes myArray[0] equal to "red",
myArray[1] equal to "blue", and myArray[2]
equal to "green". Another way to populate an array is to use
the array literal:
var myArray = ["red", "green", "blue"]
The exception to this rule of populating an array is when you use the
Array() function and give it a nonnegative integer as its only
argument:
var myArray = new Array(3)
This will instead create an array with a length property of
3. On the other hand,
var myArray = new Array("3")
will create an array with a length property of 1, and
myArray[0] equal to "3".
Properties
index
JavaScript 1.2+, JScript 5.5
Nav4+, IE4+
Syntax
var x = arrayObj.index
The index property of arrays reflects a number (which I will call n)
such that (n-1) is the character where the first match starts. If
myArray is the result of a string's match() method call,
myArray.input.charAt(myArray.index) is the first character of the first
match.
The index property only applies to arrays generated by a
match() method call of a string or an exec() method call of a
regular expression. (See Chapters 4, "String()," and 9,
"RegExp()," for more information.)
input
JavaScript 1.2+, JScript 5.5
Nav4+, IE4+
Syntax
var x = arrayObj.input
The input property of arrays reflects the string against
which the match() method call executed. If myArray is the
result of a String().match() method call,
myArray.input.charAt(myArray.index) is the first character of the first
match.
This property only applies to arrays generated by a match() method
call of a string or an exec() method call of a regular expression. (See
Chapters 4, "String()," and 9, "RegExp()," for more
information.)
length
Nav3+, IE4+
Syntax
[var x =] arrayObj.length [= newLength]
The length property of arrays typically indicates the number of
elements in the array's element list. This is a property JavaScript updates
any time the array changes.
If you reduce the length value, JavaScript crops the array until the
actual length matches the length you set. If you increase it, you add more
undefined elements to the array. But you can do the same by simply
assigning an object to the last element you want to define -everything
between the last defined value and your new defined value exists as
undefined.
myArray = ["red", "green","blue"]
myArray.length = 2
alert(myArray) // returns Array() object containing "red", "green"
However, the length property is more valuable when you retrieve its
value than when you set it. The two most common uses are to go through each
element in an array's element list, and to add new elements to the end of
the element list.
The first uses a for statement loop:
for (var loop = 0; loop < myArray.length; loop++) { /* ... */ }
The second simply assigns a value to the element index just past the last
element in the array:
myArray[myArray.length] = new Object()
Setting the length property to less than zero is forbidden; it
actually caused a crash in Netscape 4 during one of my tests. Likewise, the
length property must be an integer; decimal values are not allowed.
Methods
concat()
JavaScript 1.2+, JScript 3+
Nav4+, IE4+
Syntax
var x = arrayObj.concat(arrayObj2 [, arrayObj3...])
var x = arrayObj.concat(Obj0 [,Obj1...])
The concat() method of instances of Array() returns a new
instance of Array() with the arguments in the concat() method
attached to the end, after the this array's elements. If the
argument is an Array() object, the Array() object's
members will be appended, instead of the Array() object itself. This
does not mean a two-dimensional array's second dimension will bubble up to
directly append its elements:
myArray = new Array("3","4")
myAlt = ["5"]
alert(myArray.concat("2",myAlt, "6")) // returns ["3","4","2","5","6"]
alert(myArray.concat("2",myAlt, "6")[3].constructor)
// returns String() constructor function
myObj = new Array("x")
myObj[0] = new Array("x")
alert(myArray.concat("2", myObj )[3].constructor)
// returns Array() constructor function
This method does not change the array which it references.
join()
JavaScript 1.1, JScript 3+
Nav3+, IE4+
Syntax
var x = arrayObj.join(joinString)
The join() method of instances of Array() returns a string
containing the elements of the array in the order they held within their element
list, separated by the first argument of the method. For instance, if the
argument was ",", all elements would have a comma separating them from
other elements, and nothing else-no spaces, no line returns, and so on.
This method does not change the array which it references.
pop()
JavaScript 1.2+, JScript 5+
Nav4+, IE5.5
Syntax
var x = arrayObj.pop()
The pop() method of instances of Array() extracts the last
element of the array and returns it to the user. The last element is
removed from the array.
Developers targeting earlier browsers may emulate this using the script shown
in Listing 3.1.
Listing 3.1 Emulating Array().pop
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title></title></head>
<body>
<script language="JavaScript" type="text/javascript">
<!--
function Array_pop() {
var response = this[this.length - 1]
this.length--
return response
}
if (typeof(Array.prototype.pop) == "undefined") {
Array.prototype.pop = Array_pop
}
//-->
</script>
</body>
</html>
push()
JavaScript 1.2+, JScript 5.5+
Nav4+, IE5.5
Syntax
arrayObj.push(arg0[, arg1[, arg2...]])
The push() method of instances of Array() appends the
arguments provided in the method to the end of the array. For Netscape
4.00-4.05, this method returns the last new element of the array. For
Netscape 4.06+ and Internet Explorer 5.5, it returns the new length
property of the array.
Developers targeting earlier browsers may emulate this using the script shown
in Listing 3.2.
Listing 3.2 Emulating Array().push
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title></title></head>
<body>
<script language="JavaScript" type="text/javascript">
<!--
function Array_push() {
var A_p = 0
for (A_p = 0; A_p < arguments.length; A_p++) {
this[this.length] = arguments[A_p]
}
return this.length
}
if (typeof Array.prototype.push == "undefined") {
Array.prototype.push = Array_push
}
//-->
</script>
</body>
</html>
reverse()
JavaScript 1.1+, JScript 3+
Nav3+, IE4+
Syntax
arrayObj.reverse()
The reverse() method of instances of Array() reverses the
ordering of elements in the array's element list. For example, the first
element becomes the last element, and vice versa.
shift()
JavaScript 1.2+, JScript 5.5+
Nav4+, IE5.5+
Syntax
var x = arrayObj.shift()
The shift() method of instances of Array() extracts the
first element in the array object's element list and returns it. The
element returned is removed from the array altogether.
Developers targeting earlier browsers may emulate this using the script shown
in Listing 3.3.
Listing 3.3 Emulating Array().shift
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title></title></head>
<body>
<script language="JavaScript" type="text/javascript">
<!--
function Array_shift() {
var A_s = 0
var response = this[0]
for (A_s = 0; A_s < this.length-1; A_s++) {
this[A_s] = this[A_s + 1]
}
this.length--
return response
}
if (typeof Array.prototype.shift == "undefined") {
Array_prototype.shift = Array_shift
}
//-->
</script>
</body>
</html>
slice()
JavaScript 1.2+, JScript 3+
Nav4+, IE4+
Syntax
var x = arrayObj.slice(startPos, endPos)
The slice() method of instances of Array() returns the
elements of the this array between and including those elements whose
index numbers of the array match the two arguments for this function.
If the second argument is negative, the method stops copying the array's
elements x units from the end of the array, where x is the
absolute value of the second argument.
This method does not change the array it references.
sort()
JavaScript 1.1+, JScript 3+
Nav3+, IE4+
Syntax
arrayObj.sort([funcname])
The sort() method of instances of Array() sorts the
this array's element list according to a function you provide as
the method's only argument. Your function receives two arguments, which
represent elements in the array. Create rules describing the relationships
between these two objects. If you want the first element to precede the second
after sorting, return +1 (or any positive number). If you want the
first element to come after the second, return -1 (or any negative
number). If the order does not matter, return 0.
If you do not provide such a function, JavaScript will sort your array by
characters according to the language's ASCII codes. (This is a term
indicating a listing of characters assigned special codes. ASCII codes are
covered in more depth in Chapters 4, "String()" and 31,
"Programable Elements.") Each element of the array this method treats
as a string. This can result in 415 coming before 5. Write your sort
functions carefully.
A typical sort function for numbers in an array is found in Listing
3.4, as the sortNumbers() function.
Listing 3.4 Sorting an Array of Numbers
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title></title></head>
<body>
<p>
<script language="JavaScript" type="text/javascript">
<!--
function sortNumbers(first, second) {
return first-second
}
var x = [0, -4, 2, 6, 1]
document.write("[" + x + "] ")
x.sort(sortNumbers)
document.write("sorts as ["+ x +"].")
//-->
</script>
<!-- Result:
[0,-4,2,6,1] sorts as [-4,0,1,2,6].
-->
</p>
</body>
</html>
splice()
JavaScript 1.2+, JScript 5.5+
Nav4+, IE5.5+
Syntax
var x = arrayObj.splice(startIndex, cutTotal [, arg0 [, arg1...]])
The powerful splice() method of instances of Array() both
removes and inserts elements based on the arguments you feed it. The first
argument is an index number of the element list indicating where the method
begins its work. The second argument tells the function how many elements of the
array to remove starting at the indexed element. The remaining arguments are
elements to add to the array after its indexed element.
If only one element of the array is to be returned, Netscape 4.00-4.05
browsers will return the element. Netscape 4.06+ and Internet Explorer 5.5
browsers will return an array containing the element as its only element. If two
or more elements are to be returned, regardless of the circumstances, the method
will return an array containing their values.
Developers targeting earlier browsers can emulate this using the script shown
in Listing 3.5.
Listing 3.5 Emulating splice()
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title></title></head>
<body>
<script language="JavaScript" type="text/javascript">
<!--
function Array_splice(index, delTotal) {
var temp = new Array()
var response = new Array()
var A_s = 0
for (A_s = 0; A_s < index; A_s++) {
temp[temp.length] = this[A_s]
}
for (A_s = 2; A_s < arguments.length; A_s++) {
temp[temp.length] = arguments[A_s]
}
for (A_s = index + delTotal; A_s < this.length; A_s++) {
temp[temp.length] = this[A_s]
}
for (A_s = 0; A_s < delTotal; A_s++) {
response[A_s] = this[index + A_s]
}
this.length = 0
for (A_s = 0; A_s < temp.length; A_s++) {
this[this.length] = temp[A_s]
}
return response
}
if (typeof Array.prototype.splice == "undefined") {
Array.prototype.splice = Array_splice
}
//-->
</script>
</body>
</html>
toString()
JavaScript 1.1+, JScript 3+
Nav3+, IE4+
Overrides Object.prototype.toString()
Syntax
var x = arrayObj.toString()
The toString() method of instances of Array() simply
returns the same as this.join(","). See the join()
method description for details.
toSource()
JavaScript 1.3+
Nav4.05+
Overrides Object.prototype.toSource()
Syntax
var x = arrayObj.toSource()
The toSource() method of instances of Array() provides a
source-code breakdown of the array in question. Primarily this is for debugging
purposes only, though you can look at it to see just what's in your array.
The function returns the array as an array literal:
["red","green","blue"]
unshift()
JavaScript 1.2+, JScript 5.5+
Nav4+, IE5.5
Syntax
[var x =] arrayObj.unshift(arg0 [, arg1 [, arg2...]])
The unshift() method of instances of Array() inserts the
arguments provided to the method at the beginning of the array, moving all other
elements later in the chain. In Netscape 4+, it returns the new length of the
Array() object.
Developers targeting earlier browsers may emulate this using the script shown
in Listing 3.6.
Listing 3.6 Emulating unshift()
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title></title></head>
<body>
<script language="JavaScript" type="text/javascript">
<!--
function Array_unshift() {
var A_u = 0
for (A_u = this.length-1; A_u >= 0; A_u--) {
this[A_u + arguments.length] = this[A_u]
}
for (A_u = 0; A_u < arguments.length; A_u++) {
this[A_u] = arguments[A_u]
}
return this.length
}
if (typeof Array.prototype.unshift == "undefined") {
Array.prototype.unshift = Array_unshift
}
//-->
</script>
</body>
</html>
valueOf()
JavaScript 1.1+, JScript 3.0+
Nav3+, IE4+
Overrides Object.prototype.valueOf()
Syntax
var x = arrayObj.valueOf()
The valueOf() method of instances of Array() returns the
array itself as a literal object.
Example: An Extensible switch Function
One of the nice things about JavaScript is it is an object-oriented language.
It's built around the concept of objects, which makes it very easy to
extend the language and add capabilities, if you choose to do so. (I choose to
do so.)
The switch statement of Chapter 11 is one of the statements I like.
It allows me to compare an unknown value against a set of known values, and at
the first match, execute a code block. This makes it a very powerful feature of
the language. The only thing I don't like about it is the inability to add
new known values to the set of known values it checks against. I would have to
replace the function containing the switch statement with another
function or edit the function's source code (see Chapter 2's example
for details on this). Either way is a bit long for simply adding one more known
value.
Enter arrays. As you know, arrays can handle any kind of object or literal
value you throw at them in an element list. So suppose I have a list of known
values in an array to check an unknown value against, and a code block to
execute for each match. Then it's merely a matter of checking each element
in the array until I have a match, and if there is no match, executing the
default code.
The xswitch() script, which I provide here as Listing 3.7, does
precisely this. The xSwitchObj() function creates the array and
attaches a few methods for accessing the array. The xswitch() function
returns a code block, which you can use an eval() method call to
execute. Basically, the results have the same scope as a switch
statement would have, but also thanks to the object-oriented design they support
the capability to add new cases as the user sees fit.
Listing 3.7 The xswitch() Script with a Sample
Use
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title></title></head>
<body>
<script language="JavaScript" type="text/javascript">
<!--
function xswitch(xswitch_1, switchObj) {
var cases = switchObj.cases
var xswitch_k = 0;
var xswitch_flag = true
var response = ""
for (xswitch_k = 0; (xswitch_k < cases.length)&&(xswitch_flag); xswitch_k++) {
if (xswitch_1 == cases[xswitch_k].xswitch_2) {
response = cases[xswitch_k].code
xswitch_flag = false
}
}
if (xswitch_flag) {
response = switchObj.def
}
return response
}
function xswitchObj() {
function xaddCase(xswitch_2, code) {
this.cases[this.cases.length] = new Object()
this.cases[this.cases.length-1].xswitch_2 = xswitch_2
this.cases[this.cases.length-1].code = code
}
function xdefCase(code) {
this.def = code
}
this.cases = []
this.addCase = xaddCase
this.defCase = xdefCase
}
myCases = new xswitchObj()
myCases.defCase("alert('default case')")
myCases.addCase(1, "alert('one')")
myCases.addCase(2, "alert('two')")
eval(xswitch(3, myCases))
// executes an alert for the phrase "default case"
myCases.addCase(3, "alert('three')")
eval(xswitch(3, myCases))
// executes an alert for the word "three"
//-->
</script>
</body>
</html>
Using the xswitch function is actually fairly easy. You start by
defining a basic xswitchObj() object.
myCases = new xswitchObj()
This is not much-but I can define a default case for the new
xswitchObj() object easily:
myCases.defCase("alert('default case')")
Adding individual cases to read before the default is equally easy:
myCases.addCase(1, "alert('one')")
myCases.addCase(2, "alert('two')")
Then, to actually execute the xswitch() as intended, I simply call
an eval() of the xswitch() function, with the first argument
being the unknown value mentioned previously, and the second being the
xSwitchObj() object it is being compared against:
eval(xswitch(3, myCases))
// executes "alert('default case')" and pops up an alert
The xswitch() function searches the element list of the
xswitchObj() array passed to it for the matching value in one of its
properties. At the first match, it returns the code and breaks out of the loop.
The default case reflects here because no case has been defined for the number
3. This, however, is easily solved:
myCases.addCase(3, "alert('three')")
This time, when you call
eval(xswitch(3, myCases))
the eval() method receives
"alert('three')", which it then executes.