Dans cet article, l'auteur, développeur front-end, a donné un aperçu des principales façons de créer, modifier et comparer des objets JavaScript.Les objets sont l'un des concepts de base de JavaScript. Quand j'ai commencé à les étudier, elles me semblaient assez simples: juste quelques clés et valeurs, comme décrit en théorie.
Ce n'est qu'après un certain temps que j'ai commencé à réaliser que le sujet est beaucoup plus compliqué que je ne le pensais. Et puis j'ai commencé à étudier des informations provenant de diverses sources. Certains d'entre eux ont donné une bonne idée du sujet, mais je n'ai pas pu voir immédiatement l'image entière.
Dans cet article, j'ai essayé de couvrir tous les aspects du travail avec des objets dans JS, sans aller trop loin dans les détails individuels, mais sans manquer de détails importants qui vous aideront à comprendre le sujet et à vous sentir plus en confiance lors de son étude approfondie.
Commençons donc par les bases.
Objet
Un objet en JavaScript est simplement une collection de propriétés, chacune étant une paire clé-valeur. Les clés sont accessibles en utilisant la notation pointillée (
obj.a ) ou entre crochets (
obj ['a'] ).
N'oubliez pas que les parenthèses doivent être utilisées si la clé est:
- n'est pas un identifiant JavaScript valide (il a un espace, un tiret, il commence par un chiffre ...)
- est une variable.
L'une des propriétés que les objets de JS obtiennent lorsqu'ils sont créés s'appelle
Prototype , et c'est un concept très important.
Prototype
Chaque objet en JavaScript a une propriété interne appelée
Prototype . Dans la plupart des navigateurs, vous pouvez vous y référer sous la désignation
__proto__ .
Le prototype est un moyen de fournir l'héritage des propriétés en JavaScript. Vous pouvez donc partager des fonctionnalités sans dupliquer le code en mémoire. La méthode fonctionne en créant une relation entre deux objets.
Autrement dit, Prototype crée un pointeur d'un objet à un autre.
Chaîne prototypeChaque fois que JS recherche une propriété dans l'objet et ne la trouve pas directement sur l'objet lui-même, il vérifie la présence de la propriété dans l'objet prototype. S'il n'y a pas de propriété, JS poursuivra la recherche dans le prototype de l'objet associé. Cela continuera jusqu'à ce que JS trouve une propriété appropriée ou atteigne la fin de la chaîne.
Regardons un exemple:
var cons = function () { this.a = 1; this.b = 2; } var obj = new cons(); </i> cons.prototype.b = 3; cons.prototype.c = 4;
cons est un constructeur (juste une fonction qui peut être appelée en utilisant le
nouvel opérateur).
Sur la cinquième ligne, nous créons un nouvel objet - une nouvelle copie de
contre . Immédiatement après la création,
obj obtient également une propriété prototype.
Et maintenant nous ajoutons des propriétés (
'b', 'c' ) au prototype de l'objet
contre .
Considérez
obj :
obj.a // 1 - tout est comme
avant ,
obj.a est toujours 1.
obj.c -
obj n'a pas de propriété
c ! Cependant, comme mentionné précédemment, JS va maintenant le rechercher dans le prototype
obj et retourner une valeur de 4.
Réfléchissons maintenant à la valeur de
obj.b et à ce qu'elle deviendra lorsque nous supprimerons
obj.b ?
Obj.b est 2. Nous avons attribué la propriété
b , mais nous l'avons fait pour le prototype de
contre , donc quand nous vérifions
obj.b , nous obtenons toujours 2. Cependant, immédiatement après la suppression de
obj.b, JS ne sera plus en mesure de trouver
b à o
bj , et continuera donc la recherche dans le prototype et retournera la valeur 3.
Ensuite, je veux parler brièvement de différentes façons de créer un objet et un peu plus sur les prototypes.
Création d'objets
Littéral d'objet: let obj = {a: 1};Nous avons créé un objet avec la chaîne de prototypes suivante:
obj ---> Object.prototype ---> nullComme vous pouvez le deviner,
object.prototype est le prototype de l'objet, ainsi que la fin de la chaîne de prototypes.
Object.create (): var newObj = Object.create (obj);NewObj aura la chaîne de prototypes suivante:
newObj ---> obj ---> Object.prototype ---> nullConstructeur. Comme dans l'exemple ci-dessus, le constructeur est juste une fonction JS qui nous permet d'utiliser le
nouvel opérateur pour en créer de nouvelles instances.
Classes ES6: class rectangle { constructor(height, width) { this.height = height; this.width = width; } getArea() { return this.height * this.width; } } let square = new rectangle(2, 2);
Square est une instance du constructeur
rectangle , et nous pouvons donc appeler
square.getArea () // 4 ,
square.width , ainsi que toutes les fonctions héritées de
object.prototype .
Quelle méthode est la meilleure? Si vous prévoyez de créer plusieurs instances, vous pouvez utiliser ES6 ou le constructeur. Si vous prévoyez de créer un objet une fois, il est préférable de spécifier un littéral, car c'est le moyen le plus simple.
Et maintenant, lorsque nous avons découvert le
prototype et nous sommes familiarisés avec toutes les façons de créer de nouveaux objets, nous pouvons commencer à discuter de l'un des aspects les plus déroutants associés aux objets.
Comparaison et modification d'objets
En JavaScript, les objets sont de type référenceLorsque nous créons un objet,
laissez obj = {a: 1}; , la variable
obj obtient l'adresse dans la mémoire de l'objet, mais pas sa valeur! Il est impératif de comprendre cette différence, car des erreurs peuvent se produire autrement. Lorsque nous créons un autre objet
laissez newObj = obj , nous créons en fait un
pointeur vers une certaine zone de mémoire
obj , et non un objet complètement nouveau.
Cela signifie qu'en exécutant
newObj.a = 2 , nous changeons réellement
obj pour que
obj.a devienne 2!
Cette approche conduit facilement à l'apparition de bugs, de nombreuses entreprises travaillent avec des objets immuables. Au lieu de modifier un objet déjà créé, vous devrez à nouveau créer un nouvel objet (une copie de l'original) et y apporter déjà des modifications. C'est ainsi que des bibliothèques importantes comme Redux fonctionnent, et dans l'ensemble c'est l'un des concepts de base de la programmation fonctionnelle. Lisez plus
ici .
ÉgalitéDe ce qui précède, il s'ensuit également que deux objets ne peuvent jamais être égaux, même s'ils ont les mêmes propriétés. Cela est dû au fait que JS compare en fait l'emplacement des objets en mémoire et que deux objets ne se trouvent jamais dans la même cellule de mémoire.
Donc, vous vous êtes probablement déjà demandé comment comparer des objets ou comment effectuer diverses manipulations avec des objets, étant donné l'exigence de leur immuabilité.
Considérez quelques possibilités.
Changement d'objetSupposons qu'il soit clair que dans le bon sens, nous ne devrions pas changer d'objets, nous voulons donc créer une copie de l'objet correspondant et changer ses propriétés.
Object.assign () vient à la
rescousse .
var obj = { a : 1, b : 2}; var newObj = Object.assign({}, obj,{a:2})
Si nous voulons changer la valeur de la propriété a d'
obj , nous pouvons utiliser
object.assign pour créer une copie d'
obj et la changer.
L'exemple montre que nous créons d'abord un objet vide, puis copions les valeurs
obj et apportons nos modifications, pour finalement obtenir un nouvel objet prêt à l'emploi.
Veuillez noter que cette méthode ne fonctionnera pas pour la copie en profondeur. En parlant de copie profonde, nous voulons dire que vous devez copier un objet avec une ou plusieurs propriétés.
const obj = {a : 1, b : { a : 1 } };
Object.assign () copie les propriétés de l'objet, donc si la valeur de la propriété est un pointeur sur un objet, seul le pointeur est copié.
La copie en profondeur nécessite une opération récursive. Vous pouvez écrire une fonction ici ou simplement utiliser la méthode
_.cloneDeep de la bibliothèque
Lodash .
Comparaison d'objetsIl existe une façon intéressante de travailler avec des objets: la conversion de ligne. Dans l'exemple suivant, nous convertissons les deux objets en chaînes et les comparons:
JSON.stringify(obj1) === JSON.stringify(obj2)
Cette approche est justifiée, car au final, nous comparons des chaînes représentant un pointeur à un type de valeur. La mauvaise nouvelle est que cela ne fonctionne pas toujours, principalement parce que l'un ou l'autre ordre des propriétés de l'objet n'est pas garanti.
Une autre bonne solution consiste à utiliser la méthode
_.isEqual de
Lodash , qui effectue une comparaison approfondie des objets.
Et avant de terminer, passons en revue certaines questions fréquemment posées sur les objets. Cela aidera à approfondir le sujet et à mettre en pratique les connaissances acquises.
Essayez de réfléchir vous-même à la solution avant de lire la réponse.
Comment connaître la longueur d'un objet?
Pour obtenir la réponse, il faut trier toutes les propriétés de l'objet une par une et les compter. Il existe plusieurs façons d'effectuer cette itération:
- pour in . Cette méthode couvre toutes les propriétés dénombrables d'un objet et de sa chaîne prototype. Nous avons fait connaissance avec le prototype (et, j'espère, appris le matériau), il devrait donc être clair que l'utilisation de for in ne sera pas toujours vraie pour obtenir les propriétés de l'objet.
- Object.keys . Cette méthode renvoie un tableau avec les clés de ses propres propriétés dénombrables (appartenant à l'objet spécifié). Cette approche est meilleure, car nous ne travaillons que sur les propriétés de l'objet, sans recourir aux propriétés de prototype . Cependant, il existe des situations où vous définissez l' attribut énumérable d'une propriété sur false et object.keys finit par l' ignorer et vous obtenez un résultat incorrect. Cela se produit rarement, mais dans de tels cas, getOwnPropertyNames sera utile .
- getOwnPropertyNames renvoie un tableau contenant toutes les propres clés de l'objet (à la fois dénombrables et indénombrables).
A noter également:
- Object.values itère sur ses propres propriétés de comptage et renvoie un tableau avec les valeurs correspondantes.
- Object.entries parcourt ses propres propriétés de comptage et renvoie un tableau avec des clés et leurs valeurs .
Je pense que vous avez remarqué que la plupart des méthodes répertoriées ci-dessus renvoient un tableau. C'est l'occasion de tirer pleinement parti des méthodes JavaScript pour travailler avec les tableaux.
Une telle méthode est
array.length . En fin de compte, nous pouvons simplement écrire
let objLength = Object.getOwnPropertyNames(obj).length;
Comment vérifier si un objet est vide?
- JSON.stringify (myObj) === "{}" . Ici, nous utilisons à nouveau l'outil de conversion de chaîne, qui permet de vérifier facilement si un objet est vide (en comparant des chaînes, pas des objets).
- ! Object.keys (myobj) .length // true . Comme je l'ai mentionné, la conversion des clés d'un objet en tableau peut être très utile. Ici, nous utilisons la longueur de propriété pratique héritée de Array.prototype , vérifiant avec elle la longueur des clés dans le tableau. En JS, 0 devient faux, donc en ajoutant ! nous le transformons en vrai. Tout autre numéro deviendra faux.
En conclusion
J'espère que maintenant vous vous sentez plus en confiance pour créer des objets et travailler avec eux. Résumons:
- N'oubliez pas que les objets appartiennent au type de référence, ce qui signifie qu'il est recommandé de travailler avec eux sans modifier les objets d'origine.
- Faites-vous des amis avec la propriété du prototype et la chaîne de prototypes .
- Apprenez à connaître les outils d'aide pour travailler avec des objets. N'oubliez pas que vous pouvez transformer des objets en chaînes, obtenir un tableau avec leurs clés ou simplement parcourir leurs propriétés en utilisant un ensemble de méthodes que nous avons rencontrées.
Bonne chance pour apprendre des objets JavaScript.
