Array creation and memory allocation

D

David Golightly

Quick question for the gurus out there: in ECMAScript, one can create
a new Array object with a length like so:

var animals = new Array(128);

This creates a new Array object with a "length" property set to 128.
My question: Does this in any sense "preallocate" memory for any of
these 128 slots? I've seen the word "preallocate" bandied about, but
my experience with UAs tells me this term is being misused; all 128 of
those "slots" remain "undefined", as do all non-declared property
names on any object. In writing my own code, I've stayed away from
declaring arrays using the above syntax, as I feel it's somewhat
misleading to indicate that an amount of memory has been allocated
that's in any way proportional to the length given to the
constructor. In fact, I can't really think of much legitimate use for
creating an Array object with 128 "undefined" items, except to confuse
C++ and Java programmers. But, if it's actually allocating memory
here, maybe I'm wrong.

Thanks,
David
 
D

Douglas Crockford

David said:
Quick question for the gurus out there: in ECMAScript, one can create
a new Array object with a length like so:

var animals = new Array(128);

This creates a new Array object with a "length" property set to 128.
My question: Does this in any sense "preallocate" memory for any of
these 128 slots? I've seen the word "preallocate" bandied about, but
my experience with UAs tells me this term is being misused; all 128 of
those "slots" remain "undefined", as do all non-declared property
names on any object. In writing my own code, I've stayed away from
declaring arrays using the above syntax, as I feel it's somewhat
misleading to indicate that an amount of memory has been allocated
that's in any way proportional to the length given to the
constructor. In fact, I can't really think of much legitimate use for
creating an Array object with 128 "undefined" items, except to confuse
C++ and Java programmers. But, if it's actually allocating memory
here, maybe I'm wrong.

You have it right. I use [] exclusively, for the reasons you presented.
 
R

Richard Cornford

David said:
Quick question for the gurus out there: in ECMAScript, one
can create a new Array object with a length like so:

var animals = new Array(128);

This creates a new Array object with a "length" property set
to 128.
My question: Does this in any sense "preallocate" memory for
any of these 128 slots?

The answer would be 'maybe, but probably not'. The important detail is
that even if the length property is pre-set to some value that action
should not result in the creation of any 'array index' properties of the
Array object, and without the creation of any 'array index' properties
there is no need for memory to be allocated to accommodate them.
Javascript arrays are supposed to be sparse. Whether some internal
details of the implementation of an Array could be optimised with some
internal pre-allocation of memory would depend on the implementation,
but the javascript programmer should not be able to tell whether that
was happening or not.
I've seen the word "preallocate" bandied about, but
my experience with UAs tells me this term is being misused;
all 128 of those "slots" remain "undefined", as do all
non-declared property names on any object.

For-in loops, or - hasOwnProperty - tests, would be more informative as
an object can have a property but that property can hold the undefined
value.
In writing my own code, I've stayed away from
declaring arrays using the above syntax, as I feel it's
somewhat misleading to indicate that an amount of memory
has been allocated that's in any way proportional to the
length given to the constructor. In fact, I can't really
think of much legitimate use for creating an Array object
with 128 "undefined" items, except to confuse C++ and Java
programmers. But, if it's actually allocating memory
here, maybe I'm wrong.

I would go along with Douglas Crockford here and just use empty Array
literals to create new Arrays, and forget about any notion of
pre-declaring the length.

Richard.
 
E

Evertjan.

Richard Cornford wrote on 18 sep 2007 in comp.lang.javascript:
I would go along with Douglas Crockford here and just use empty Array
literals to create new Arrays, and forget about any notion of
pre-declaring the length.

While post-declaring is usable:

<script type='text/javascript'>

var a = [];
a[17] = 'x';
a['notAnArrayMember'] = 'y'
alert(a.length); // 18
a.length = 3;
alert(a.length); // 3
alert(a[17]); // undefined
alert(a['notAnArrayMember']); // y

</script>

IE7 tested.

Would memory space garbage collection be a reason to do this?
 
T

Thomas 'PointedEars' Lahn

Richard said:
I would go along with Douglas Crockford here and just use empty Array
literals to create new Arrays, and forget about any notion of
pre-declaring the length.

JFTR: The (empty) Array literal notation is not universally supported.

The alternative that is supported since the Array feature was introduced,
is

new Array()

See http://PointedEars.de/scripts/es-matrix


PointedEars
 
D

David Golightly

I would go along with Douglas Crockford here and just use empty Array
literals to create new Arrays, and forget about any notion of
pre-declaring the length.

That's what I've been doing, but looking through the code for
SpiderMonkey (Mozilla's JS engine) confirmed that this is indeed the
case (apologies for the C code on the JS list):

mozilla/js/src/jsarray.c: 2032:

static JSBool
Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
*rval)
{
jsuint length;
jsval *vector;

/* If called without new, replace obj with a new Array object. */
if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
if (!obj)
return JS_FALSE;
*rval = OBJECT_TO_JSVAL(obj);
}

if (argc == 0) {
length = 0;
vector = NULL;
} else if (argc > 1) {
length = (jsuint) argc;
vector = argv;
} else if (!JSVAL_IS_NUMBER(argv[0])) {
length = 1;
vector = argv;
} else {

/******
We would get here using eg. new Array(128)
*/

if (!ValueIsLength(cx, argv[0], &length))
return JS_FALSE;
vector = NULL;
}
return InitArrayObject(cx, obj, length, vector);
}

/mozilla/js/src/jsarray.c: 779:

static JSBool
InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval
*vector)
{

/******
in the above example (new Array(128)), we would get here with params:
cx = <irrelevant context reference>, JSObject == <new Array
instance>, length == 128, vector == NULL
*/

jsval v;

JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_ArrayClass);
if (!IndexToValue(cx, length, &v))
return JS_FALSE;
STOBJ_SET_SLOT(obj, JSSLOT_ARRAY_LENGTH, v);


/******
since "vector" is NULL, this test fails, returning TRUE;
InitArrayElements never gets called
*/

return !vector || InitArrayElements(cx, obj, 0, length, vector);
}
 

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

Forum statistics

Threads
474,156
Messages
2,570,878
Members
47,408
Latest member
AlenaRay88

Latest Threads

Top