Object-Oriented JavaScript: Part 2 | Page 3
[previous]
Object-Oriented JavaScript: Part 2
Thinking of Objects as Associative Arrays
A key element in understanding JavaScript objects is understanding the notion of associative arrays, which are nothing more than collections of (key, value) pairs. As a.NET developer you have worked with associative arrays represented by classes such as NameValueCollection
, Hashtable
, dictionaries, and others. Unlike with normal arrays, where the key is numeric (as in bookNames[5]
), the key of an associative array is usually a string, or even other kinds of objects that can represent themselves as strings. For example, take a look at the following code snippet, where we retrieve the name of the book by specifying a unique string value that identifies that book:
The concept is simple indeed. In this case, the key and the value of the bookNames
associative array are both strings. This associative array could then be represented by a table like this:
The table above can be represented in JavaScript, as an associative array, like this:
The key of an element doesn't have to be literal; it can even be specified through a variable:
In JavaScript, however, the implementation of the associative array is more powerful, in that it makes no restriction on the type of the value of the (key, value) pair. The value can be a number, a string, a date, or even a function! This flexibility allows us to represent JavaScript objects as associative arrays. For example, an instance of the Table
class that we discussed earlier can be represented like this:
[ The literal notation of creating JavaScript objects has one weakness—it can only be used to describe objects. In other words, using the literal notation you can only define (key, value) pairs, but you can't create classes, class constructors, or other reusable components of code. ]
Creating Object Members on the Fly
One major difference between OOP in C# and ASP.NET, and OOP in JavaScript, is that JavaScript allows creating object members "on the fly". This is true for objects and classes that you create yourself and also for JavaScript's own objects and types as well. Here's an example where we add a field named ImADate
to a JavaScript Date
object:
A typical OOP language such as C#, VB.NET, or Java, doesn't allow you to create members on the fly, like JavaScript does. Instead, each member must be defined formally in the definition of the class.
Private Members
JavaScript doesn't support the notion of private members as C# does, but you can simulate the functionality by using variables inside the function. Variables are declared with the var
keyword or are received as function parameters. They aren't accessed using this
, and they aren't accessible through function instances, thus acting like private members. Variables can, however, be accessed by closure functions.
If you want to test this, modify the Table function as shown below.
This time we persist the values received as parameters as local variables named _rows
and _columns
. Note they aren't referred to using this
any more. Local variables names don't need to start with an underscore, but this is a useful naming convention that specifies they are meant to be used as private members. You can make a short test that the "private" members can't be accessed from outside the function, and that getCellCount()
still works, using code such as the following. The results are shown in Figure 3-5.
This exercise reveals that _rows
and _columns
aren't accessible from outside the function's scope. Their values read undefined because there are no fields named _rows
and _columns
in the Table
function. The getCellCount()
function, on the other hand, can read _rows
and _columns
as variables because they are in the same closure. As you can see, although the implementation and behavior are somewhat different than in C#, you still have a way of defining internal (private) members inside a function.
[This is an excerpt from the book, Microsoft AJAX Library Essentials: Client-side ASP.NET AJAX 1.0 Explained, by Cristian Darie, Bogdan Brinzarea . Published by Packt Publishing Ltd., 2007
[previous]
URL: