3

I have the following JavaScript code. I have initialised an array using the new keyword, and therefore creating a new instance of the array object. I then populate the array by adding elements to it.

However I think I have made a fundamental misunderstanding - it is the next part of the code that has massively confused me, please correct my terminology if it is not clear enough or it is just plain wrong. I have logged (beatles.length). I am using the length property to find out how many elements are in the array. But why is it that length is a property and not a method?

Is it not the case that length is actually a method that the Array object can invoke that returns a numeric value? If length is not a method then why is it a property (a variable belonging to the array object)? Please explain the distinction here in a succinct way.

var beatles = new Array();
beatles[0] = "John";
beatles[1] = "Paul";
beatles[2] = "George";
beatles[3] = "Ringo";

console.log(beatles.length);
2
  • It's less memory intensive to have it be an integer property that changes on every array change than calling a method every time. In some JS engines, it may be a getter method. Commented Jan 22, 2013 at 17:31
  • Take a look here: developer.mozilla.org/en-US/docs/JavaScript/Reference/… Commented Jan 22, 2013 at 17:31

7 Answers 7

3

It is a property that gets increased or decreased as you push elements to the array object.

For example my (fake) object:

var myArray = function(){
   this.length = 0;

   this.push = function(itm){
       this.length++; 
       // ^ doesn't do anything aside from increase length
   };
};
Sign up to request clarification or add additional context in comments.

Comments

2

Both String and Arrays are of the type Objects and are not basic variable types.

So, the length is a member variable of the Object generic object and is commonly available to both Array as well as String. In case of String, it returns the string length and in the case of Array, it returns the count, by overriding.

A small example would be:

var a = "Hello";
var b = new Array();
b[0] = "Hello";
b[1] = "World";
a.length    // returns 5
b.length    // returns 2

1 Comment

Although both String and Array have .length, it's NOT a member of Object.
2

there is no need for .length to be a function, since it doesn't need to be recalculated every time, but rather it's increased or decreased as needed as you push elements onto your [] object.

while functions can be idempotent, properties are always idempotent, which makes .length a better fit as well.

functions generally change state (like .push), or return different values based on the arguments they receive (.slice, .splice).

on a different note:

the preferred way to initialize arrays is var a = [];, and to add elements you should use a.push(element);

1 Comment

Is the idempotent statement still true for the new ES5/6 standard? Will there be provisions to prevent mutations in get-implementation? That would be a bit strange.
2

length is a pseudo-property, there is something going on under-the-hood to make it work like it does.

length behaves like a getter and a setter in one (like a function). You access it like a property, but you can't delete it like a property: delete beatles.length (will fail).

If you add elements to the Array the length property will change accordingly.

If you set the length property, the Array will change - beatles.length = 0; will clear the Array.

Right now there is no way to make similar functionality yourself (short of using explicit get/setter). Some of this will become available in the new ES5 (or 6?) standard. Like the ability to make immutable properties. That magic of indexed assignments will be specific to Arrays though, that's a language feature.

As for why the language designer made it property instead of a function .. well, perhaps performance, perhaps similarity to other languages (most notably Java of course).

Source:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/get https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/set

Comments

2

The Array.length property is actually an encapsulation of two (hidden) methods, get() and a set() , also referred to as accessors.

JavaScript internally calls get() when you use the property in an expression, e.g.:

var n = fields.length;

Conversely, it calls set() when used in an assignment, e.g.:

fields.length = 1;

Doing so also updates the array items to satisfy the following condition.

The value of the length property is always one higher than the biggest item index (or zero if there are none);

This is an important detail, because in certain cases it will not strictly be the same as the number of (non-null) items in the array.

Comments

1

In this case, length is a property which is always kept valid by the javascript engine itself.

Comments

1

It's a property, but it's unlike any other property in the whole language.

Arrays aren't quite the same kind of object that you're familiar with (though they do come quite close). The spec defines a special type of object, called an Array exotic object, just to keep the length property working quite the way it should, and all Arrays are actually this kind of exotic object, rather than standard objects. There are a few other kinds of exotic objects, too, but the one for Arrays is what concerns us here.

The basics of the length property seem simple enough: it's the number of elements in the Array. But keeping this up-to-date requires a considerable amount of behind-the-scenes magic. Even getters and setters can't completely handle it.

The reason comes from the actual definition of the Array length property: if you look at the property names of an object, it might be possible to express some of them as numbers, and if this is possible, then one of the numbers must be larger than all of the others. Array exotic objects always have a property called length, and that property's value must always be larger than the largest such number for its object. If other properties change, then the Array's length might have to change too, depending on the name of the other property. So it has to monitor all property changes, to make sure that it updates when it's supposed to.

Currently, there's no way to do that in JavaScript. You can have functions monitor changes to a specific property, by using setters, but you can't have a general function to monitor all property changes on an object. ECMAScript 6 looks like it will have a way to do this, via Proxy objects, but there aren't any browsers that support it completely just yet.

4 Comments

Well, you could do a getter for the .length and every time it is accessed search the whole array index space for the highest one :-)
@Bergi: That's true. I guess you could do that. It wouldn't scale very well to large Arrays, though.
@Bergi Is there a way to reconfigure an array's length property to have a getter? I believe it's not configurable.
@Redu Yes, native arrays have a non-configurable length

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.