90 votes

Les index négatifs dans les tableaux JavaScript doivent-ils contribuer à la longueur du tableau ?

En javascript, je définis un tableau comme ceci

var arr = [1,2,3];

Je peux aussi faire

arr[-1] = 4;

Maintenant si je fais

arr = undefined;

Je perds également la référence à la valeur à arr[-1] .

Donc pour moi, logiquement, il semble que arr[-1] soit aussi une partie de arr .

Mais quand je fais ce qui suit (sans mettre arr à undefined)

arr.length;

Il retourne 3 no 4 ;

Donc mon point de vue est si les tableaux peuvent être utilisés avec des index négatifs, ces indices négatifs devraient également faire partie de leur longueur**. Je ne sais pas, peut-être que je me trompe ou qu'il me manque un concept sur les tableaux.

120voto

Andrew Whitaker Points 58588

Donc pour moi, logiquement, il semble que arr[-1] soit aussi une partie de arr.

Oui, mais pas de la manière dont vous le pensez.

Vous pouvez assigner des propriétés arbitraires à un tableau (comme n'importe quel autre objet en JavaScript), ce que vous faites lorsque vous "indexez" le tableau à -1 et lui attribuer une valeur. Puisqu'il ne s'agit pas d'un membre du tableau mais simplement d'une propriété arbitraire, vous ne devez pas vous attendre à ce que length pour considérer cette propriété.

En d'autres termes, le code suivant fait la même chose :

​var arr = [1, 2, 3];

​arr.cookies = 4;

alert(arr.length) // 3;

26voto

nnnnnn Points 70578

En length renvoie un nombre supérieur d'une unité à l'"indice" le plus élevé attribué, les "indices" du tableau étant des entiers supérieurs ou égaux à zéro. Notez que JS autorise les tableaux "épars" :

var someArray = [];
someArray[10] = "whatever";
console.log(someArray.length); // "11"

Bien sûr, s'il n'y a pas d'éléments, alors length es 0 . Notez également que le length n'est pas mis à jour si vous utilisez delete pour retirer l'élément le plus élevé.

Mais les tableaux sont des objets, et vous pouvez donc attribuer aux propriétés d'autres noms de propriétés arbitraires, y compris des nombres négatifs ou des fractions :

someArray[-1] = "A property";
someArray[3.1415] = "Vaguely Pi";
someArray["test"] = "Whatever";

Notez que, dans les coulisses, JS convertit les noms de propriétés en chaînes de caractères, même si vous fournissez un nombre tel que -1 . (Les indices des nombres entiers positifs deviennent également des chaînes de caractères, d'ailleurs).

Les méthodes de tableau, comme .pop() , .slice() etc., ne fonctionnent que sur les "indices" entiers nuls ou supérieurs, et non sur les autres propriétés, donc length est cohérent sur ce point.

9voto

Jonathan Sampson Points 121800

Notez que lorsque vous utilisez un index de position (ou 0), les valeurs sont placées dans le tableau :

var array = [];

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

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

Ce n'est pas le cas lorsque vous ajoutez des valeurs non indexées (pas 0-9+) :

var array = [];

array[0]  = "Foo";
array[1]  = "Bar";
array[-1] = "Fizzbuzz"; // Not a proper array index - kill it

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

Les valeurs ne sont placées dans le tableau que si vous respectez les règles. Si vous ne le faites pas, elles ne sont pas acceptées. Elles sont cependant acceptées sur l'objet Array lui-même, ce qui est le cas pour à peu près tout en JavaScript. Même si ["Foo", "Bar"] sont les seules valeurs dans notre tableau, nous pouvons toujours accéder à "Fizzbuzz" :

array[-1]; // "Fizzbuzz"

Mais notez encore une fois que cela ne fait pas partie des valeurs du tableau, puisque son "index" n'est pas valide. Il a été ajouté au tableau comme un membre supplémentaire. Nous pouvons accéder aux autres membres du tableau de la même manière :

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

Notez ici que nous accédons au pop sur le tableau, ce qui nous informe que celui-ci contient du code natif. Nous n'accédons pas à l'une des valeurs du tableau dont la clé est "pop", mais plutôt à un membre de l'objet tableau lui-même. Nous pouvons confirmer cela en parcourant les membres publics de l'objet :

for (var prop in array) 
    console.log(prop, array[prop]);

Ce qui donne le résultat suivant :

 0 Foo
 1 Bar
-1 Fizzbuzz

Donc, encore une fois, c'est sur le site objet mais ce n'est pas le cas. sur le site tableau .

Question géniale ! Ça m'a fait réfléchir à deux fois, c'est sûr.

5voto

David Sherret Points 3205

Si vous voulez vraiment que les index négatifs et autres soient inclus dans la longueur, alors créez la fonctionnalité vous-même :

function getExtendedArray() {
    var a = [];

    Object.defineProperty(a, 'totalLength', { 
        get : function() { return Object.keys(a).length; }
    });

    return a;
}

Alors par exemple :

var myArray = getExtendedArray();
console.log(myArray.totalLength); // 0
myArray.push("asdf");
myArray[-2] = "some string";
myArray[1.7777] = "other string";
console.log(myArray.totalLength); // 3

4voto

Tony R Points 2433

Les tableaux en JavaScript sont en fait des objets. Ils sont simplement prototypés à partir du constructeur Array.

Les indices des tableaux sont en fait des clés dans un hashmap, et toutes les clés sont converties en chaînes de caractères. Vous pouvez créer n'importe quelle clé (par exemple "-1"), mais les méthodes de Array sont conçues pour agir comme un tableau. Ainsi, length n'est pas la taille de l'objet, il est plutôt garanti qu'il soit plus grand que le plus grand indice entier. De même, l'impression arr ne listera que les valeurs dont les clés sont des entiers >= 0.

Plus d'informations ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X