Section K. Associative arrays


K. Associative arrays

We saw that test.a granted access to the a property of the test object. However, there is a second way of accessing the same property: test['a']. Similarly, test.c() can also be written as test['c'](). This is a very important bit of JavaScript lore.

The general rule is that the following two expressions are the same:

object.property; object['property']; 


The following two expressions are also the same:

object.method(); object['method'](); 


Note that the bit inside the square brackets is a string. The two examples above use the literal strings 'property' and 'object', but it's of course possible to first create a string as a variable and then insert the variable name in the square brackets:

var iWantThisProperty = 'money'; var myHappiness = thingsToHave[iWantThisProperty]; 


This is the same as saying:

var myHappiness = thingsToHave.money; 


Nonetheless, there's a difference in ease of programming. With dot notation, you must type the name of the property directly in your code. A script cannot change the literal code thingsToHave.money in any way; it always means "The money property of the thingsToHave object."

On the other hand, with square-bracket notation, changing the name of the property is easy as pie; you just create the string you need and put it between the []. The code example above does so: it first creates the string iWantThisProperty, and then uses its value to call the correct property of the object myHappiness.

Square bracket vs. dot notation

In Edit Style Sheet, the form fields have the name and value of the style they should change. For instance, this is the form field where the user can specify the CSS text-align property:

<select name="textAlign" >     <option value="">not specified</option>     <option value="left">Left</option>     <option value="center">Center</option>     <option value="right">Right</option> </select> 


The select's name is textAlign (which, as we'll see in 9A, is the JavaScript equivalent to CSS text-align). The values of the options are the values this CSS declaration can take: left, center, or right.

When the user changes the select box, a function should start up that sets the correct CSS property (defined in the form field's name) to the correct value (defined in the form field's value). Suppose the user selects 'center'.

The dot notation doesn't work here. Suppose I did this:

[Edit Style Sheet, lines 57-64, condensed and changed]

   function assignStyles() {      var styleName = this.name;      var styleValue = this.value;      currentRule.style.styleName = styleValue;  } 


Although extracting styleName and styleValue is easy, the currentRule.style.styleName doesn't work. The function therefore changes style's property named styleName:

currentRule.style.styleName = 'center'; 


You want to say "The property whose name is the value of variable styleName gets the value 'center'," but this statement always literally means "The styleName property of the object gets the value 'center'."

As we saw, you're allowed to define any property you like, so this statement is not wrong and doesn't give error messages. Nonetheless, it doesn't do what you want, either.

To solve this problem, you must use the square-bracket notation. This notation expects a string, and that's exactly what styleName contains:

[Edit Style Sheet, lines 57-64, condensed]

function assignStyles() {     var styleName = this.name;     var styleValue = this.value;     currentRule.style[styleName] = styleValue; } 


Now the function takes the string that's the value of the variable styleName, and uses this string to determine which property of currentRule.style should get the value 'center'.

Therefore, if the user changes the select box to 'center', the last line reads:

currentRule.style['textAlign'] = 'center'; 


Now we change the correct property, and the style change takes effect immediately.

Associative arrays

Associative arrays are arrays that allow you to find a certain value by using a string as the name of this value. These strings are called keys. A key now becomes associated with a certain value.

This is an example of a pure associative array from Form Validation:

[Form Validation, lines 8-13]

var validationFunctions = new Object(); validationFunctions["required"] = isRequired; validationFunctions["pattern"] = isPattern; validationFunctions["postcode"] = isPostCode; validationFunctions["numeric"] = isNumeric; validationFunctions["email"] = isEmail; 


Note that we start out by making validationFunctions an object. This is required.

Now the validationFunctions object serves as a lookup table for the various form-validation functions. The trick is that I use the keys to this lookup table (required, pattern, etc.) as values of the custom validation attribute:

<input name="phone" validation="required numeric" /> 


The script reads out these values and uses them as keys to access the correct validation functions in validationFunctions.

[Form Validation, lines 82-88, changed and condensed]

var field = [form field]; var reqs = field.getAttribute('validation').split(' '); for (var j=0;j<reqs.length;j++) {     var isValid = validationFunctions[reqs[j]](field); 


The function splits the validation attribute's value on spaces. As we saw in 5F, this yields an array, which it stores in reqs. Now the function loops through all elements in this reqs array and uses the values it finds as keys.

Thus it finds the function it should execute: validationFunctions[reqs[j]]. The return value of this function is used to determine whether the form field is valid.

Another example of an associative array functioning as a lookup table can be found in 8K.

The for in statement

The for in statement goes through all keys of an associative array (which is the same as going through all properties of an object). In general, you use the square-bracket notation when you do something with these keys.

Let's take our test object and use the for in statement on it:

var test = {     a: 2,     b: '2',     c: function () {            alert(this.a * this.b);     } } for (var i in test) {     alert(i + ': ' + test[i]); } 


Now you see three alerts: the first two show '2', and the last one shows the entire function c.

Note that I use square-bracket notation (test[i]) to actually read out the value of the properties. If I used dot notation (test.i) I'd encounter the same problem as before: It would mean "The i property of object test" (which is undefined), instead of "The property of test whose name is stored in i."

Edit Style Sheet contains a practical example of for in. At a certain point I want to read out all styles that are currently contained in one style rule. currentRule.style is an object and contains a property for every style that can be defined:

[Edit Style Sheet, lines 68-70, changed]

var z = currentRule.style; for (var i in z) {     if (z[i]) { // simplified situation                 // store default styles     } } 


The for (var i in z) loop now goes through every property of object z, which means every possible style that could be set on the style rule. Since that also includes all empty styles, I also check if the property has a value at all (if (z[i])).

If it doesn't have a value, I ignore it. If it does have a value, I store this value for future reference.



ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net