10

I know the universal way of changing an array's size is to use .push().

However, today I saw a piece of code in angularJS that does something like this:

var service = {
   pages: [],
   doSmth: doSmth
};

doSmth();

function doSmth() {
   service.pages[1] = "abc";
   service.pages[5] = "def";
}

I ran the debugger on the browser and found that before doSmth() is called, pages[1] is undefined, but after that, pages[1] is assigned the value without any error.

How is this possible?

7
  • 3
    Because pages already been initialized in pages: [] . Without pages:[], you would see the undefined error. Commented Nov 24, 2015 at 20:52
  • 5
    Assigning values to indices at or past an array’s length will resize it to fit. Commented Nov 24, 2015 at 20:52
  • What behaviour did you expect? remember that function doSmth is hoisted Commented Nov 24, 2015 at 20:52
  • 1
    You can always just add an element to an array at any index and it will "resize" (in so far as the length will appear to be the largest index + 1) to fit. The push function is just a convenience to add an element to myarray[myarray.length] Commented Nov 24, 2015 at 20:55
  • 1
    @PTN: There are no OutOfBounds in Javascript. Commented Nov 24, 2015 at 20:56

3 Answers 3

21

That's just the magic that JavaScript allows. If you come from a language like Java or C, this may seem like a weird idea, but you can set the value of any index in the array at any time, and the array will expand to that size!

Consider:

var t = [];
t.length === 0;
t[10000] = 'value';
t.length === 10001;

JavaScript just handles this behind the scenes. It's worth mentioning that this behavior is not specific to JavaScript. This is seen a bit in other interpreted languages as well. Ruby, for example, allows you to do the same.

Additionally in JavaScript, length is a writeable attribute of arrays, so you can easily truncate or clear an entire array:

var t = [1];
t[4] = 0;
t === [1, undefined, undefined, undefined, 0];
t.length = 2;
t === [1, undefined];
t.length = 0;
t === [];

Setting the length to 0 is one of the fastest and simplest ways to clear an array. It might not be the most intuitive solution, but it's my go-to.

Sign up to request clarification or add additional context in comments.

2 Comments

Note: The array may not actually expand. It will behave as if it did, but internally, depending on the implementation, it may well not have actually assigned any extra space.
And all this is formally described in specification ecma-international.org/ecma-262/5.1/#sec-15.4.5.1
3

An array in JavaScript is just an object with some special properties. Essentially, they are just objects with positive, integer property names. There are some other key differences, but the idea is that you could do this:

var obj = { };
obj['1'] = 'abc';

So you can do the same with an array.

However! You shouldn't. Modern JavaScript engines usually optimize arrays by backing them with fast, native implementations. By setting indexes that are not currently allocated will de-optimize your code into something more like an object, which is much slower.

5 Comments

but this is not what is happening
var obj = { }; <- you are initializing an object, not array. obj = [] is array.
@CodeiSir: In what way?
@minitech see my answer, its not the same namespace
@tanjir, I understand, Array's are just specialized JS Objects. I was showing the basic way of how you can set any property on an object. I like Brennans anwer best for explaining the extra magic.
0

Pages in function doSmth() is not in the same namespace as pages in service, wich is service.pages.

Your pages[1] musst be a global declared somewhere else.

However you are initializing pages as an empty (but existing) array: pages: [],

var service = {
    pages: [],
    doSmth: doSmth
};

doSmth();

function doSmth() {
    pages[1] = "abc";
    pages[5] = "def";
}

Comments

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.