Nous traitons des objets en JavaScript

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 prototype

Chaque 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 ---> null
Comme 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 ---> null

Constructeur. 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érence

Lorsque 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.

 // Two distinct objects with the same properties are not equal var fruit = {name: 'apple'}; var fruitbear = {name: 'apple'}; fruit === fruitbear; // return false // here fruit and fruitbear are pointing to same object var fruit = {name: 'apple'}; var fruitbear = fruit; fruit === fruitbear; // return true 

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'objet

Supposons 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}) // {a : 2, b : 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 } }; // b property is an object 

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'objets

Il 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?


  1. 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).
  2. ! 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.

image

Source: https://habr.com/ru/post/fr419193/


All Articles