Objects disguised as Arrays

L

Laser Lips

/*I was messing about with accossiative arrays when I discovered that
an
accossiative array does not have a length.*/

var myAsso = [];
myAsso["one"]="one";
myAsso["two"]="two";
myAsso["three"]="three";
alert(myAsso.length); //=0

/*I see that arrays can have mixed key attributes of both
numbers(index) and strings (accossiative), but the array's length will
only be counted using the indexed based keys.*/


var myArr=[];
myArr[0]="my value";
myArr[1]="my value";
myArr[2]="my value";
myArr["3"]="my value"; //this one is still classed as an index
myArr["a"]="my value";
myArr["b"]="my value";
myArr["c"]="my value";
myArr["d"]="my value";

alert("Array length = " + myArr.length); //length = 4

//the following loop will pick of the index based keys
for(var x=0;x<myArr.length;x++)
{
alert("for x) "+x + " = "+myArr[x]);
}
//the following loop will pick of the accossiative based keys
for(var n in myArr)
{
alert("for in) "+n + " = " + myArr[n]);
}
//add an accossiative element
myArr[4]="my value";

alert("Array length = " + myArr.length);//length = 5

//able to add a function to the array.
myArr.test=function()
{
alert("Func");
}
myArr.test();
alert("Array length = " + myArr.length);//length = 5

Even though I can add functions to the array, the array is still
classed as an array because it has length attribute.

Why do the accossiative based keys not get counted?

Graham
 
J

Joe Nine

Laser said:
Even though I can add functions to the array, the array is still
classed as an array because it has length attribute.

Why do the accossiative based keys not get counted?

Graham

Because they're not really array elements, they're just properties of
the array. Just like you could say myArray.myId="user array" and
myArray2.myId="customer array" and then pass one of those arrays to a
function and it could check receivedArray.myId to see which array it
got. They're not real associative keys, they just act like them in many
(but not all) ways.
 
D

Dmitry A. Soshnikov

/*I was messing about with accossiative arrays when I discovered that
an
accossiative array does not have a length.*/

var myAsso = [];
myAsso["one"]="one";
myAsso["two"]="two";
myAsso["three"]="three";
alert(myAsso.length);  //=0

/*I see that arrays can have mixed key attributes of both
numbers(index) and strings (accossiative), but the array's length will
only be counted using the indexed based keys.*/

                var myArr=[];
        myArr[0]="my value";
        myArr[1]="my value";
        myArr[2]="my value";
        myArr["3"]="my value"; //this one is still classed as an index
        myArr["a"]="my value";
        myArr["b"]="my value";
        myArr["c"]="my value";
        myArr["d"]="my value";

        alert("Array length = " + myArr.length); //length = 4

        //the following loop will pick of the index based keys
        for(var x=0;x<myArr.length;x++)
        {
                alert("for x) "+x + " = "+myArr[x]);
        }
        //the following loop will pick of the accossiative based keys
                for(var n in myArr)
                {
                                alert("for in) "+n + " = " + myArr[n]);
                }
        //add an accossiative element
                myArr[4]="my value";

                alert("Array length = " + myArr.length);//length = 5

        //able to add a function to the array.
                myArr.test=function()
                {
                                alert("Func");
                }
                myArr.test();
                alert("Array length = " + myArr.length);//length = 5

Even though I can add functions to the array, the array is still
classed as an array because it has length attribute.

Why do the accossiative based keys not get counted?

First of all you should remember, that in ECMAScript _only strings_
can be used as a property names of objects.

var a = [];
a[1] = 10;
alert(a['1']); // 10

In contrast with other language (Ruby, Python) which can use any
_hashable_ object as keys of other object, ECMAScript uses only
strings. So you can write something like this:

var a = {x: 10};
var b = [];
b[a] = 10;

And that even will work:

alert(b[a]); // 10

But it doesn't mean that object `b` (array) has another object as one
of its properties. It just will be converted to string (in default
representation "[object Object]"):

alert(b['[object Object]']); // 10

var otherKey = {};
alert(b[otherKey]); // also converted - 10

About arrays - yes, they have overloaded [[Put]] method (this method
is called every time we created/modify a property) and `length` is
modified by some conditions one of which - property name should be
number-indexed (which then if needed is converted again to string).

Dmitry.
 
R

Richard Cornford

/*I was messing about with accossiative arrays

Or at least you think you were.
when I discovered that an
accossiative array does not have a length.*/

It can be (has been, and at considerable length) argued that
javascript objects are not associative arrays and should not be spoken
of as such. For one thing, they don't have a length property that
relates to the number of properties they have (or that are assigned to
them), while a particular notion of what an associative arrays is
would require that they did. Secondly, javascript objects are never
'empty' (never have zero properties, because they always inherit some
(at least in ES<=3), while that is something that an associative
arrays should be capable of being.
var myAsso = [];
myAsso["one"]="one";
myAsso["two"]="two";
myAsso["three"]="three";
alert(myAsso.length); //=0

/*I see that arrays can have mixed key attributes of both
numbers(index) and strings (accossiative),

Javascript is required to behave as if all of the property names of
all objects (including Array objects) are strings.
but the array's length will
only be counted using the indexed based keys.*/

Arrays are distinct from other objects in that they have a specific
internal [[Put]] method that may modify the objects - length -
property if the property name used with [[Put]] is an 'array index'
property, and may delete array properties if the property name used
with [[Put]] is "length". Apart from that they behave just like any
other native object.
var myArr=[];
myArr[0]="my value";
myArr[1]="my value";
myArr[2]="my value";
myArr["3"]="my value"; //this one is still classed as an index
myArr["a"]="my value";
myArr["b"]="my value";
myArr["c"]="my value";
myArr["d"]="my value";

alert("Array length = " + myArr.length); //length = 4

//the following loop will pick of the index based keys
for(var x=0;x<myArr.length;x++)
{
alert("for x) "+x + " = "+myArr[x]);
}
//the following loop will pick of the accossiative based keys
for(var n in myArr)
{
alert("for in) "+n + " = " + myArr[n]);
}

The for-in loop should loop over all of the enumerable property names
of any object. For an array these should include all 'array index'
property names, but the array's - length - property is non-enumerable.

If you used - (typeof n) - to show the type of the n value for each
enumerable property the result would be 'string' for all properties,
including the 'array index' properties (at least in any environment
more recent than Netscape 4).

//add an accossiative element
myArr[4]="my value";

alert("Array length = " + myArr.length);//length = 5

//able to add a function to the array.
myArr.test=function()
{
alert("Func");
}
myArr.test();
alert("Array length = " + myArr.length);//length = 5

Even though I can add functions to the array, the array is still
classed as an array because it has length attribute.

Object with - length - properties (even non-enumerable - length -
properties) are not necessarily arrays. It is the distinct internal
[[Put]] method that distinguishes an array from other types of objects
(even in ES 5 the array's internal [[Class]] property is not
discriminating by specification).
Why do the accossiative based keys not get counted?

Because they do not satisfy the rules for an 'array index' property
name.

Richard.
 
R

RobG

Or at least you think you were.


It can be (has been, and at considerable length) argued that
javascript objects are not associative arrays and should not be spoken
of as such.

It makes life difficult when people better proliferate the idea that
ECMAScript objects are associative arrays. I tried to change the entry
on Wikipedia some time ago, only to have the changes reverted by
someone who thought otherwise:

| JavaScript objects are associative arrays, augmented with
| prototypes (see below).

For one thing, they don't have a length property that
relates to the number of properties they have (or that are assigned to
them), while a particular notion of what an associative arrays is
would require that they did. Secondly, javascript objects are never
'empty' (never have zero properties, because they always inherit some
(at least in ES<=3), while that is something that an associative
arrays should be capable of being.

For some, the fact that they have name/value pairs is sufficient,
despite missing some other very important features normally associated
with associative arrays.
 
D

Dmitry A. Soshnikov

It makes life difficult when people better proliferate the idea that
ECMAScript objects are associative arrays. I tried to change the entry
on Wikipedia some time ago, only to have the changes reverted by
someone who thought otherwise:

| JavaScript objects are associative arrays, augmented with
| prototypes (see below).



For some, the fact that they have name/value pairs is sufficient,
despite missing some other very important features normally associated
with associative arrays.

The main point is in semantics and syntax rules used for access keys
(which are called as "properties" of an object). In other languages,
e.g. in Ruby or Python, hashes/dictionaries also can have
"prototypes" (classes) to which objects delegate if haven't own such
properties. But there in contrast with ECMAScript semantic of bracket
and dot notations is _discriminated_. So it doesn't mean that hash-
table should have a prototype - if to manage it correctly (e.g.
discriminating access to "keys" and to "properties/methods") -
everything is fine.

If to make brief conclusion of why objects in ECMAScript can be named
as "hashes" (and similar terms such as "dictionaries", "hash maps",
"associative arrays", etc) and why not are:

1) Can be named if:

- theoretical data structure is meant in definition of "key-value"
pairs. Because "associative arrays" - is just a theoretical data
structure (an abstract data type) and exist independently concrete
languages and implementations.

2) Cannot be named because of:

- the same semantics of dot and bracket notations for property access;
- delegation to prototypes;
- there is only one object type in ECMAScript and its "subtypes"
beside values (and presence) of internal properties (such as
[[Class]], [[Call]], etc) in respect of storing "key-value" pairs do
not differ from each other.

<URL: http://dmitrysoshnikov.com/ecmascript/chapter-7-2-oop-ecmascript-implementation/#associative-arrays>

Dmitry.
 
D

Dmitry A. Soshnikov

On Mar 23, 12:43 pm, "Dmitry A. Soshnikov"

[...]
So it doesn't mean that hash-
table should have a prototype - if to manage it correctly (e.g.
^^^^^^^^^

Typo, should be "it does not mean that hashes should not have
prototypes", because they can (in meaning of delegation based
prototyping when object will delegate for the not found own property).

Also the important addition: in languages (all the same Ruby and
Python) there is discrimination not only in semantics of dot and
bracket notation, but also discrimination in semantics of
"keys"/"array indexes" and "properties/methods". In ECMAScript this
case is simplified and there are only "properties" for all this cases
and semantics of bracket and dot property accessors isn't
discriminated.

E.g. in Ruby:

a = {}
a.class # hash

a.length # 0

# new key-value pair
a['length'] = 10;

# and semantics for dot notation
# is still meaning access to
# the property/method

a.length # 1

# and this is access to the key

a['length'] # 10

Usually in Ruby _symbols_ (a special data type, values of which are
prefixed with a colon) are used as keys of hashes, so we can add
another _key_ with the "same" name:

a[:length] = 20

print(a) # {"length" => 10, :length => 20}

And still semantics of property/method .length is another:

a.length # 2
a['length'] # 10
a[:length] # 20

We can augment `Hash` class with new property/method and it (via
delegation) will be allowed for the instances:

class Hash
def z
100
end
end

# new _property_ is available

a.z # 100

But it is not a _key_:

a['z'] # nil

In Python the situation is similar (although we can't augment built-
ins, but can augment inherited from the built-ins).

Dmitry.
 
R

Richard Cornford

It makes life difficult when people better proliferate the idea
that ECMAScript objects are associative arrays. I tried to
change the entry on Wikipedia some time ago, only to have the
changes reverted by someone who thought otherwise:

| JavaScript objects are associative arrays, augmented with
| prototypes (see below).

<URL:http://en.wikipedia.org/wiki/Javascript#Dynamic>

It has been observed often enough that it is very common for people's
confidence in their own understanding of javascript to far exceed its
reality. Wikipedia suffers from the odd problem of ending up
representing the truth as defined by the most persistent.
For some, the fact that they have name/value pairs is sufficient,

Hence the arguments.
despite missing some other very important features normally
associated with associative arrays.

I would like the question to be; what explanation of javascript
objects best promotes the better understanding of the subject in its
readers? Having seen/read many explanations, and many expressions of
misconceptions following from various and varied explanations I
wouldn't mention "associative arrays" in relation to javascript
objects at all. If the reader brings any preconceptions about
associative arrays with them then they are invariable disappointed,
and those without preconceptions don't have any (or much of a) notion
of what an associative array is and do don't need to hear the term at
all.

When the OP wrote of "messing about with accossiative arrays" and
discovering that "an accossiative array does not have a length" we see
a disappointed expectation where there never was any reason for
promoting that expectation in the first place.

Richard.
 
D

Dmitry A. Soshnikov

[...]
For some, the fact that they have name/value pairs is sufficient,
despite missing some other very important features normally associated
with associative arrays.

What exactly do you mean by "other very important features"? You said
so like "key-value" pairs is not so important feature of associative
arrays, but in fact, it is the most important feature. And in general
this data structure is not required to have `length` property. If you
meant some variations such as multivalue hashes and so on - that's OK,
but still the main feature of this abstract data structure - is an
_association_ (mapping) of a key and a value corresponding to this
key. Just like a function is defined for some arguments: y = f(x).

And repeat regarding ECMAScript - there isn't discrimination because
of the same meaning of "keys" and "properties", "properties" and
"array indexes", dot notation and bracket notation for accessing this
"keys/properties/indexes/methods" - only because of this.

But on implementation level (of many ECMAScript implementations) -
exactly hash tables are used, but implementation level - is already
another level of abstraction and ECMAScript provides its own
abstraction level where there are only concept of an object.

Dmitry.
 
D

Dmitry A. Soshnikov

On Mar 23, 3:43 pm, Richard Cornford <[email protected]>
wrote:

[...]
I would like the question to be; what explanation of javascript
objects best promotes the better understanding of the subject in its
readers?

The best way just to say that ECMAScript provides another abstraction
level where there is only concept of an object and implementation
details (of what exactly is used to implement these objects - hash
tables, trees or anything else) - is not so essential.

Also here possible to show some simple abstract example demonstrating
why the term "hash" can be improper regarding ES (with mentioning the
same semantics for property accessor notations and respectively the
same semantics for "keys/properties/array-indexes").

Dmitry.
 
K

Ken Snyder

...
Why do the accossiative based keys not get counted?
...

As others have mentioned, there is no such thing as associative arrays
in JS.

Also note that JS arrays are sparse, but report length as if they are
not. Consider the following:

var a = [];
a[0] = "zero";
a[2] = "two";

In JS, the array `a` occupies the same memory as an array filled with
two consecutively numbered items. but:

a.length; // 3
a.join(','); // zero,,two

So in JS, the length is equal to the highest numbered key minus one.

- Ken
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top