109 votes

Pourquoi puis-je ajouter des propriétés nommées à un tableau comme s'il s'agissait d'un objet?

Les deux extraits de code suivants me semblent équivalents :

var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";

et

var myObject = {'A': 'Athens', 'B':'Berlin'};

parce qu'ils se comportent de la même manière, et aussi typeof(myArray) == typeof(myObjects) (les deux renvoient 'object').

Y a-t-il une différence entre ces variantes ?

134voto

Paul Dixon Points 122033

Presque tout en javascript est un objet, donc vous pouvez "abuser" d'un objet Array en définissant des propriétés arbitraires dessus. Cela doit être considéré comme dangereux. Les tableaux sont destinés aux données indexées de manière numérique - pour les clés non numériques, utilisez un objet.

Voici un exemple plus concret de pourquoi les clés non numériques ne "conviennent pas" à un Array:

var monTableau = Array();
monTableau['A'] = "Athènes";
monTableau['B'] = "Berlin";

alert(monTableau.length);

Cela n'affichera pas '2', mais '0' - en effet, aucun élément n'a été ajouté au tableau, seulement de nouvelles propriétés ont été ajoutées à l'objet tableau.

4 votes

MyArray.length renvoie un index/clé numérique du dernier élément dans un tableau mais pas le nombre réel d'éléments. Les propriétés de l'objet Array ne sont-elles pas les mêmes que les valeurs du tableau?

1 votes

Je tentais simplement d'illustrer que la sémantique prévue de l'objet Array est maltraitée si on le traite simplement comme un objet standard. Cependant, l'article lié le fait mieux :)

13 votes

La prochaine fois que quelqu'un dit que JavaScript est un bon langage de développement, je lui montrerai cet exemple. Merci.

14voto

Casey Points 2020

En JS, les tableaux sont des objets, simplement légèrement modifiés (avec quelques fonctions supplémentaires).

Fonctions comme :

concat
every
filer
forEach
join
indexOf
lastIndexOf
map
pop
push
reverse
shift
slice
some
sort
splice
toSource
toString
unshift
valueOf

0 votes

Bien que je ne pense pas que toutes les fonctions répertoriées soient intégrées dans chaque implémentation de JS, tu as compris le point. L'autre différence serait un prototype différent (ce qui est implicite par ces fonctions supplémentaires).

5voto

Ekim Points 395

Je pense que ma réponse précédente était trop métaphorique et cryptique. Voici des clarifications.

Une instance d'Array, Boolean, Date, Function, Number, RegExp, String est un Object mais améliorée avec des méthodes et propriétés spécifiques à chaque type. Par exemple, un tableau a une propriété prédéfinie length alors que les objets génériques n'en ont pas.

javascript:alert([].length+'\n'+{}.length)

affiche

0
undefined

De manière intrinsèque, l'interpréteur FF Gecko fait également la distinction entre les Arrays et les objets génériques avec des différences distinctes lors de l'évaluation des constructions de langage.

javascript:
  ra=[  "one",   "two",   "three"]; ra.a=4;
  ob={0:"one", 1:"two", 2:"three"}; ob.a=4;
  alert(
    ra            +"\n\n"+
    ob            +"\n\n"+
    ra.toSource() +"\n\n"+
    ra.a          +"\t .toSource() m'a oublié ! \n\n"+
    ra.length     +"\t et ma longueur ! \n\n"+
    ob.toSource());
  ps=""; for(i in ra)ps+=i+" "; alert(ps);  /* NB .length is missing! */
  ps=""; for(i in ob)ps+=i+" "; alert(ps);

affiche

one,two,three

\[object Object\]

\["one", "two", "three"\]

4    .toSource() m'a oublié ! 

3    et ma longueur ! 

({0:"one", 1:"two", 2:"three", a:4})

ainsi que 0 1 2 a et 0 1 2 a.

Concernant l'affirmation que tous les objets sont des fonctions :

Il n'est ni syntaxiquement ni sémantiquement correct d'utiliser une instance d'objet arbitraire comme une fonction comme 123() ou "abc"() ou []() ou {}() ou obj()obj est de type autre que Function, donc une instance d'objet arbitraire n'est pas une Function. Cependant, étant donné un objet obj et son type comme Array, Boolean, Date, ..., comment obj est-il devenu un Array, Boolean, Date, ...? Qu'est-ce qu'un Array, Boolean, Date, ... ?

javascript:
    alert([Array, Boolean, Date, Function, 
              Number, Object, RegExp, String] . join('\n\n') );

affiche

function Array() {
    [native code]
}

function Boolean() {
    [native code]
}

function Date() {
    [native code]
}

function Function() {
    [native code]
}

function Number() {
    [native code]
}

function Object() {
    [native code]
}

function RegExp() {
    [native code]
}

function String() {
    [native code]
}

Dans tous les cas, sans équivoque, le type d'objet se manifeste comme une définition de function, d'où l'affirmation que tous les objets sont des fonctions ! (L'ironie est que j'ai intentionnellement obscurci et brouillé la distinction d'une instance d'objet avec celle de son type! Cela montre néanmoins que "on ne peut pas avoir l'un sans l'autre", Objet et Fonction! La capitalisation souligne le type par opposition à l'instance.)

Un paradigme à la fois fonctionnel et orienté objet semble être fondamental pour la programmation et la mise en œuvre des primitives intégrées de bas niveau de l'interpréteur JS, telles que Math et JSON et true.

 javascript:alert([Math, JSON, true.toSource()].join("\n\n"));

affiche

[object Math]

[object JSON]

(new Boolean(true))

À l'époque du développement de Javascript, un style de programmation centré sur les objets (OOP's - style de programmation orienté objet - le "'s" est mon propre jeu de mots !) était à la mode et l'interpréteur a été également baptisé Java pour lui donner plus de crédibilité. Les techniques de programmation fonctionnelle étaient reléguées à des examens plus abstraits et ésotériques étudiant les théories des automates, des fonctions récursives, des langues formelles, etc. et en tant que telles, elles n'étaient pas aussi palatables. Cependant, les forces de ces considérations formelles sont clairement manifestes dans Javascript, particulièrement tel qu'implémenté dans le moteur Gecko de FF (c'est-à-dire .toSource()).


La définition d'objet pour Function est particulièrement satisfaisante car elle est définie comme une relation de récurrence ! définie en utilisant sa propre définition !

function Function() { [code natif] }
et comme une fonction est un Objet, le même sentiment s'applique à
function Object() { [code natif] }.

La plupart des autres définitions se terminent par une valeur terminale statique. Cependant, eval() est une primitive particulièrement puissante et donc une String peut également incorporer une fonctionnalité arbitraire.

Remarquez encore une fois que le langage utilisé ci-dessus obscurcit la distinction entre le type d'objet et l'instance.

5voto

Dasha Salo Points 2893

Tout en JavaScript est un objet, en dehors des types primitifs.

Le code

var myArray = Array();

crée une instance de l'objet Array tandis que

var myObject = {'A': 'Athènes', 'B':'Berlin'};

crée une instance de l'objet Object.

Essayez le code suivant

alert(myArray.constructor)
alert(myObject.constructor)

Vous verrez donc la différence dans le type du constructeur d'objet.

L'instance de l'objet Array contiendra toutes les propriétés et méthodes du prototype Array.

-1voto

Dario Points 26259

La notation {} n'est qu'un sucre syntaxique pour rendre le code plus agréable ;-)

JavaScript a de nombreuses constructions similaires comme la construction de fonctions, où function() est juste un synonyme de

var Func = new Function("", "");

3 votes

Le constructeur de fonction n'est PAS un synonyme du littéral de fonction. Le littéral est défini de manière lexicale tandis que le constructeur est global. {} est une notation d'objet littéral, [] est un tableau littéral, je ne suis pas sûr de ce que vous voulez dire dans votre réponse.

0 votes

Aussi, les fonctions déclarées sont disponibles avant que le code ne soit exécuté, les affectations utilisant le constructeur Function ne sont pas disponibles tant que le code qui les crée n'est pas exécuté.

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