分享
 
 
 

Objects as associative arrays

王朝other·作者佚名  2006-04-24
窄屏简体版  字體: |||超大  

URL: http://www.quirksmode.org/js/associative.html

On this page I explain how JavaScript objects are also associative arrays (hashes). Using these you can associate a key string with a value string, which can be very useful sometimes.

Suppose you have a combined mouseover / click script. You want to keep track of the status of each image, whether it is normal, mouseovered or clicked. In addition you want to be able to reach this status by image name. So if you have an image named 'Home' you want to read out

theStatus['Home']

and get one of the values 'normal', 'mouseover' or 'clicked', corresponding to the current status of the image.

To do this you need JavaScript objects.

Objects in JavaScript

JavaScript is an object oriented language. However, in practice objects defined by the programmer himself are rarely used, except in complex DOM API's. Of course such standard objects as window and document and their numerous offspring are very important, but they are defined by the browser, not by the programmer.

I myself have written JavaScript for more than three years without ever defining an object. The technique explained on this page is the first practical use of programmer-defined objects I've found.

Since the only other programming languages I know are Commodore 64 Basic (which is not object oriented, to put it mildly) and Perl (which doesn't need to be object oriented) and since I don't have any formal training in programming I cannot write a general introduction to objects and object oriented programming. Therefore a quick overview will have to suffice.

Methods and properties

In JavaScript you can define your own objects. In addition, you can assign methods and properties to each object, pre-written or self-defined.

Methods are 'things that do something', they can be recognized by their brackets (). When you call them, like object.method(), something happens.

Properties are 'things that are something'. They have a value, for instance a number, a string or a Boolean value. When you call them, like object.property, you get (or set) this value.

Normal JavaScript functions are also methods (hence the brackets). If you do

document.write('text')

you execute the pre-defined write() method of the document object. If you write your own functions you add methods to the window object, the parent of all other JavaScript objects.

Likewise, if you ask for the innerHeight of a page, you access a property of the window object and if you define a variable of your own you really add a new property to the window object.

So you already use methods and properties in everyday JavaScripting. Since most of these are preprogrammed functions and variables, you usually don't need to worry about the objects themselves, they're just a kind of 'black boxes' that contain useful stuff. The methods and properties (functions and variables) that you define yourself are usually added to the window object.

Defining an object and properties

But now we want to create an object of our own. This is simple:

var theStatus = new Object;

Now we have initialized our theStatus object and we can start adding properties (in this example we don't need methods). What we want is to create one property for each image on the page. We could do

theStatus.Home = 'normal';

Now we have added a new property Home to our object and set its value to the string 'normal'. (Remember that JavaScript is case sensitive, so the property home does not exist, only Home.)

All this is very useful, but using this notation we encounter problems later on. Suppose we want to create a property of theStatus for each image on the page. The property should have the same name as the image and its value should be 'normal'.

We cannot do:

var x = document.images;

for (var i=0;i<x.length;i++)

{

var theName = x[i].name;

theStatus.theName = 'normal';

}

We go through the entire images array of the page, take the name of each image and then try to create a new property with the same name. But the code above doesn't work. Each time you do

theStatus.theName = 'normal';

JavaScript faithfully creates a new property named theName and sets its value to 'normal'. After executing this script you have only one property theName. This is not what we want, we want one property for each image.

Associative arrays

So we have to use one of JavaScript's minor mysteries. In JavaScript, objects are also associative arrays (or hashes). That is, the property

theStatus.Home

can also be read or written by calling

theStatus['Home']

Thus, you can access each property by entering the name of the property as a string into this array. Such an array associates each key with a value (in this case the key Home is associated with the value normal). In the Perl programming language it is also called a hash.

Unlike Perl, which requires you to create such an associative array explicitly, JavaScript automatically creates a associative array for each object.

You see this behaviour with common objects like a form. You can access a form by performing either of these DOM calls:

document.forms['theForm']

document.forms.theForm

(You can also use document.theForm but that's a special case, not regular behaviour of JavaScript objects/associative arrays).

So when we want to set the status of each image to 'normal' in our object, we do

var x = document.images;

for (var i=0;i<x.length;i++)

{

var theName = x[i].name;

theStatus[theName] = 'normal';

}

and it works. Now theName (a string) is put into the brackets [] where a string is expected. So you create a new key/value pair, which is the same as a new property with a value.

All this is JavaScript magic at its fullest. I don't completely understand what I'm doing either, but it works just fine. Basically you now have the power to let one name or string refer to another one.

for (var i in object)

for (var i in object) is equivalent to Perl foreach $key (keys %hash).

Just as you can go through each element of a normal array by

var x = [the array];

for (var i = 0;i<x.length;i++)

{

do something with x[i]

}

you can also go through each element of an associative array. Suppose you want to go through the status values of all images. If the status of the image is 'mouseover' you want to call a function callFn() and pass the image name to it. You can of course tediously write out everything:

if (theStatus.Home == 'mouseover')

callFn('Home'):

if (theStatus.Place == 'mouseover')

callFn('Place'):

etc.

or

if (theStatus['Home'] == 'mouseover')

callFn('Home'):

if (theStatus['Place'] == 'mouseover')

callFn('Place'):

etc.

But this quickly leads to immense scripts. Besides, if you rename an image later on you also have to change a line of code and of course you forget, so you get errors etc.

Fortunately JavaScript has the for/in statement which is meant exactly for this situation. If you do

for (var i in theStatus)

{

if (theStatus[i] == 'mouseover')

callFn(i)

}

you go through all properties of the theStatus object (= all keys in the associative array theStatus). The variable i succesively becomes the name of each property of the object (key of the associative array) so you can do something with theStatus[i] and it is done to each property.

In this case, if an image status has the value 'mouseover' you call callFn() and pass it the key (the name of the image).

(Note that JavaScript doesn't guarantee any particular order for the properties. So you cannot expect the property that was defined first to appear first, it might come last.)

Test script

A tiny script for your testing pleasure. If you click this link this script is executed:

var theStatus = new Object();

function testIt()

{

theStatus.Home = 'mouseover';

theStatus['Place'] = 'click';

for (var i in theStatus)

{

alert('theStatus[\''+i+'\'] is ' + theStatus[i])

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有