Access negative index of an array

5

BUG?

I was building a library for handling Arrays and I came across the following situation: When adding a value to a negative index within my Array, this index does not appear when using some methods:

Example:

var array = new Array("Maria", "João", "Carlos");
array[-3] = "Bernardo";

console.log(array[-3]); //Bernardo
console.log(array.length); //3
console.log(JSON.stringify(array)); //"["Maria", "João", "Carlos"]"

Note that the quantity continues to be 3 when using length and the JSON.stringify method shows only the 3 originals, however, when displaying the array[-3] the name comes correctly.

Question:

The correct one would not appear length = 4 and appear in method JSON.stringify ? Why does this occur? Is it some kind of language that allows me to add a value to a negative index?

    
asked by anonymous 04.08.2014 / 20:09

3 answers

7

In ECMAScript (JavaScript and ActionScript base) arrays are not "special" in any way: they are just an object normal with a length attribute. This means that:

  • Internally, your keys are strings, not integers:

    var arr = [10, 20, 30];
    console.log(arr[0]);   // 10
    console.log(arr["0"]); // também 10
    
  • You can add any additional property you want:

    var arr = [10, 20, 30];
    arr.teste = 42;
    console.log(arr.teste);    // 42
    console.log(arr["teste"]); // 42
    

In general, objects that have type Array are in charge of updating their length as numeric (non-negative) properties are added. This occurs regardless of whether they are added with push , numeric index, or string index:

var arr = [];  // length: 0
arr.push(10);  // length: 1
arr[1] = 20;   // length: 2
arr["2"] = 30; // length: 3
arr[10] = null; // length: 11

But if you add other properties, of any type, it considers that this is just a "normal" property - which has nothing to do with arrays - and does not handle length :

arr.foo = "bar"; // length: 11
arr["foo"] = 42; // length: 11
arr["+"] = 9001; // length: 11
arr["-3"] = 123; // length: 11

That's why you can add elements to a "negative index": because ECMAScript does not consider this as an "index", but only as a normal property.

Examples in jsFiddle . In the Chrome console, it shows not only the indexes indexed but also the "single" properties. Ex: [10, 20, 30, 10:null, foo:"bar"]

    
04.08.2014 / 20:27
2

Javascript arrays do not have negative indexes.

What happens here is that you are creating a new property on the object Array , named "-3".

The same thing happens if you use a word. For example:

var v = new Array("abra", "cadabra", "alacazan");
v["-5"] = "isto não é um índice";
v["banana"] = "muito menos isto";
v[-7] = "nem isto";

v.length // 3
v["-5"] // "isto não é um ndice" 
v.banana // "muito menos isto"
v["banana"] // "muito menos isto"
v["-7"] // "nem isto"
    
04.08.2014 / 20:19
1

I found the answer to the @mgibsonbr correct, but a bit confusing. I'm going to leave my contribution, a translation and adaptation of SOEn's response , which makes it more obvious to JavaScript burricos like me. >. <

When you reference an index or position directly, values are added to the array:

var array = [];

array[0] = "Foo";
array[1] = "Bar";

// Result: ["Foo", "Bar"]
// Length: 2

This is not the case when referencing negative indexes:

var array = [];

array[0]  = "Foo";
array[1]  = "Bar";
array[-1] = "Fizzbuzz"; // Índice inválido - Pega, Rex! Pega!

// Result: ["Foo", "Bar"]
// Length: 2

The values will only be added if you play according to the rules. If you do not follow them, the values will not be added. Simple as that!

But although they are not accepted as part of the dataset, information associated with the negative indices is supported by the Array object , so you can still access this value like any other property:

array[-1]; // "Fizzbuzz"

When we construct an Array object, even if we have not defined any value for it, it is not empty, after all, all methods belonging to the object, whether native or prototyped, are already there and can even be accessed in the same way:

array["pop"]; // function pop() { [native code] }

Here we access the prop index that is not a valid index for the data set, but is valid as Array object property and is associated with the native code Array.pop () .

And so property as length and methods like Array. prototype.pop () or Array.prototype.slice ( ) , which work only with integer and positive indexes show different results than you expect.

Once again, to reinforce. The value is not in the array and is in the Array object.

    
04.08.2014 / 21:33