You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/04-prototype-methods/article.md
+25-27Lines changed: 25 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ Bien qu'il existe également une méthode spéciale pour cela :
16
16
17
17
-[Object.create(proto, [descriptors])](mdn:js/Object/create) -- crée un objet vide avec `proto` donné comme `[[Prototype]]` et des descripteurs de propriété facultatifs.
18
18
19
-
Par exemple:
19
+
Par exemple:
20
20
21
21
```js run
22
22
let animal = {
@@ -25,7 +25,7 @@ let animal = {
25
25
26
26
// créer un nouvel objet avec animal comme prototype
27
27
*!*
28
-
let rabbit =Object.create(animal); //same as {__proto__: animal}
28
+
let rabbit =Object.create(animal); //identique à {__proto__: animal}
29
29
*/!*
30
30
31
31
alert(rabbit.eats); // true
@@ -41,7 +41,7 @@ Object.setPrototypeOf(rabbit, {}); // change le prototype de rabbit en {}
41
41
42
42
La méthode `Object.create` est un peu plus puissante, car elle a un deuxième argument facultatif : les descripteurs de propriété.
43
43
44
-
Nous pouvons fournir des propriétés supplémentaires au nouvel objet, comme ceci:
44
+
Nous pouvons fournir des propriétés supplémentaires au nouvel objet, comme ceci:
45
45
46
46
```js run
47
47
let animal = {
@@ -59,31 +59,30 @@ alert(rabbit.jumps); // true
59
59
60
60
Les descripteurs sont dans le même format que décrit dans le chapitre <info:property-descriptors>.
61
61
62
-
Nous pouvons utiliser `Object.create` pour effectuer un clonage d'objet plus puissant que la copie des propriétés dans la boucle `for..in`:
62
+
Nous pouvons utiliser `Object.create` pour effectuer un clonage d'objet plus puissant que la copie des propriétés dans la boucle `for..in`:
Cet appel crée une copie véritablement exacte de `obj`, y compris de toutes les propriétés: énumérable et non, des propriétés de données et des accesseurs/mutateurs - tout, et avec le bon `[[Prototype]]`.
70
+
Cet appel crée une copie véritablement exacte de `obj`, y compris de toutes les propriétés: énumérable et non-énumérable, des propriétés de données et des accesseurs/mutateurs - tout, et avec le bon `[[Prototype]]`.
71
71
72
72
## Bref historique
73
73
74
74
Il y a tellement de façons de gérer `[[Prototype]]`. Comment est-ce arrivé ? Pourquoi ?
75
75
76
-
77
76
C'est pour des raisons historiques.
78
77
79
-
L'héritage prototypal était dans la langue depuis son aube, mais les façons de le gérer ont évolué au fil du temps.
78
+
L'héritage prototypal était dans le langage depuis son aube, mais les façons de le gérer ont évolué au fil du temps.
80
79
81
80
- La propriété `prototype` d'une fonction constructeur fonctionne depuis des temps très anciens. C'est la manière la plus ancienne de créer des objets avec un prototype donné.
82
81
- Plus tard, en 2012, `Object.create` est apparu dans la norme. Il a donné la possibilité de créer des objets avec un prototype donné, mais n'a pas fourni la possibilité de l'obtenir/le définir. Certains navigateurs ont implémenté l'accesseur non standard `__proto__` qui permettait à l'utilisateur d'obtenir/définir un prototype à tout moment, pour donner plus de flexibilité aux développeurs.
83
-
- Plus tard, en 2015, `Object.setPrototypeOf` et `Object.getPrototypeOf` ont été ajoutés à la norme, pour exécuter la même fonctionnalité que `__proto__`. Comme `__proto__` était de facto implémenté partout, il était en quelque sorte obsolète et a fait son chemin vers l'annexe B de la norme, c'est-à-dire: facultatif pour les environnements sans navigateur.
84
-
- Plus tard, en 2022, il a été officiellement autorisé à utiliser `__proto__` dans les objets littéraux `{...}` (supprimés de l'annexe B), mais pas en tant que getter/setter `obj.__proto__` (toujours dans Annexe B).
82
+
- Plus tard, en 2015, `Object.setPrototypeOf` et `Object.getPrototypeOf` ont été ajoutés à la norme, pour exécuter la même fonctionnalité que `__proto__`. Comme `__proto__` était de facto implémenté partout, il était en quelque sorte obsolète et a fait son chemin vers l'annexe B de la norme, c'est-à-dire facultatif pour les environnements sans navigateur.
83
+
- Plus tard, en 2022, il a été officiellement autorisé d'utiliser `__proto__` dans les objets littéraux `{...}` (sortie de l'annexe B), mais pas en tant que getter/setter `obj.__proto__` (toujours dans l'annexe B).
85
84
86
-
Pourquoi `__proto__` a été remplacé par les fonctions `getPrototypeOf/setPrototypeOf` ?
85
+
Pourquoi `__proto__` a été remplacé par les fonctions `getPrototypeOf`/`setPrototypeOf` ?
87
86
88
87
Pourquoi `__proto__` a-t-il été partiellement réhabilité et son utilisation autorisée dans `{...}`, mais pas en tant que getter/setter ?
89
88
@@ -92,7 +91,7 @@ C'est une question intéressante, qui nous oblige à comprendre pourquoi `__prot
92
91
Et bientôt nous aurons la réponse.
93
92
94
93
```warn header="Ne changez pas `[[Prototype]]` sur des objets existants si la vitesse est importante"
95
-
Techniquement, nous pouvons accéder/muter `[[Prototype]]` à tout moment. Mais en général, nous ne le définissons qu’une fois au moment de la création de l’objet, puis nous ne modifions pas : `rabbit` hérite de `animal`, et cela ne changera pas.
94
+
Techniquement, nous pouvons accéder/muter `[[Prototype]]` à tout moment. Mais en général, nous ne le définissons qu’une fois au moment de la création de l’objet, puis nous ne le modifions pas : `rabbit` hérite de `animal`, et cela ne changera pas.
96
95
97
96
Et les moteurs JavaScript sont hautement optimisés pour cela. Changer un prototype "à la volée" avec `Object.setPrototypeOf` ou `obj.__ proto __=` est une opération très lente, elle rompt les optimisations internes pour des opérations d'accès aux propriétés d'objet. Alors évitez-la à moins que vous ne sachiez ce que vous faites, ou que la vitesse de JavaScript n'a pas d'importance pour vous.
98
97
```
@@ -101,24 +100,24 @@ Et les moteurs JavaScript sont hautement optimisés pour cela. Changer un protot
101
100
102
101
Comme nous le savons, les objets peuvent être utilisés en tant que tableaux associatifs pour stocker des paires clé/valeur.
103
102
104
-
...Mais si nous essayons de stocker des clés *fournies par l'utilisateur* (par exemple, un dictionnaire saisi par l'utilisateur), nous verrons un petit problème intéressant: toutes les clés fonctionnent très bien, sauf `"__proto __"`.
103
+
...Mais si nous essayons de stocker des clés *fournies par l'utilisateur* (par exemple, un dictionnaire saisi par l'utilisateur), nous verrons un petit problème intéressant: toutes les clés fonctionnent très bien, sauf `"__proto __"`.
105
104
106
-
Découvrez l'exemple:
105
+
Découvrez l'exemple:
107
106
108
107
```js run
109
108
let obj = {};
110
109
111
110
let key = prompt("What's the key?", "__proto__");
112
111
obj[key] = "some value";
113
112
114
-
alert(obj[key]); // [object Object], pas "some value"!
113
+
alert(obj[key]); // [object Object], pas "some value"!
115
114
```
116
115
117
-
Ici, si l'utilisateur tape `__proto__`, l'assignation à la ligne 4 est ignorée!
116
+
Ici, si l'utilisateur tape `__proto__`, l'assignation à la ligne 4 est ignorée!
118
117
119
118
Cela pourrait sûrement être surprenant pour un non-développeur, mais assez compréhensible pour nous. La propriété `__proto__` est spéciale : elle doit être soit un objet, soit `null`. Une chaîne de caractères ne peut pas devenir un prototype. C'est pourquoi une affectation d'une chaîne à `__proto__` est ignorée.
120
119
121
-
Mais nous n'avions pas *l'intention* de mettre en œuvre un tel comportement, non? Nous voulons stocker des paires clé / valeur, et la clé nommée `"__proto __"` n'a pas été correctement enregistrée. Donc c'est un bug!
120
+
Mais nous n'avions pas *l'intention* de mettre en œuvre un tel comportement, non? Nous voulons stocker des paires clé/valeur, et la clé nommée `"__proto__"` n'a pas été correctement enregistrée. Donc c'est un bug!
122
121
123
122
Ici les conséquences ne sont pas terribles. Mais dans d'autres cas, nous pouvons stocker des objets au lieu de chaînes dans `obj`, puis le prototype sera effectivement modifié. En conséquence, l'exécution ira mal de manière totalement inattendue.
...Mais la syntaxe `Object` est souvent plus attrayante, car elle est plus concise.
143
142
144
-
Heureusement, nous *pouvons* utiliser des objets, car les créateurs de langages ont réfléchi à ce problème il y a longtemps.
143
+
Heureusement, nous *pouvons* utiliser des objets, car les créateurs du langage ont réfléchi à ce problème il y a longtemps.
145
144
146
-
Comme nous le savons, `__proto__` n'est pas une propriété d'un objet, mais un accesseur de propriété de `Object.prototype`:
145
+
Comme nous le savons, `__proto__` n'est pas une propriété d'un objet, mais un accesseur sur la propriété `Object.prototype`:
147
146
148
147

149
148
150
-
Ainsi, si `obj.__ proto__` est lu ou muté, l'accésseur/mutateur correspondant est appelé à partir de son prototype et il accède/mute `[[Prototype]]`.
149
+
Ainsi, si `obj.__proto__` est lu ou muté, l'accésseur/mutateur correspondant est appelé à partir de son prototype et il accède/mute `[[Prototype]]`.
151
150
152
-
Comme il a été dit au début de cette section de tutoriel: `__proto__` est un moyen d'accéder `[[Prototype]]`, il n'est pas `[[Prototype]]` lui-même.
151
+
Comme il a été dit au début de cette section de tutoriel: `__proto__` est un moyen d'accéder `[[Prototype]]`, il n'est pas `[[Prototype]]` lui-même.
153
152
154
153
Maintenant, si nous avons l'intention d'utiliser un objet comme tableau associatif et de ne pas avoir de tels problèmes, nous pouvons le faire avec une petite astuce :
155
154
156
155
```js run
157
156
*!*
158
157
let obj =Object.create(null);
159
-
//or: obj = { __proto__: null }
158
+
//ou : obj = { __proto__: null }
160
159
*/!*
161
160
162
161
let key =prompt("What's the key?", "__proto__");
@@ -165,16 +164,15 @@ obj[key] = "some value";
165
164
alert(obj[key]); // "some value"
166
165
```
167
166
168
-
`Object.create(null)` crée un objet vide sans prototype (`[[Prototype]]` est `null`):
167
+
`Object.create(null)` crée un objet vide sans prototype (`[[Prototype]]` est `null`):
169
168
170
169

171
170
172
171
Donc, il n'y a pas d'accésseur/mutateur hérité pour `__proto__`. Maintenant, il est traité comme une propriété de données normale, ainsi l'exemple ci-dessus fonctionne correctement.
173
172
174
173
Nous pouvons appeler de tels objets des objets "très simples" ou "dictionnaire pur", car ils sont encore plus simples que les objets simples ordinaires `{...}`.
175
-
Nous pouvons appeler ces objets "très simple" car ils sont encore plus simples qu'un objet ordinaire `{...}`.
176
174
177
-
L'inconvénient est que de tels objets ne possèdent aucune méthode d'objet intégrée, par exemple `toString`:
175
+
L'inconvénient est que de tels objets ne possèdent aucune méthode d'objet intégrée, par exemple `toString`:
178
176
179
177
```js run
180
178
*!*
@@ -186,7 +184,7 @@ alert(obj); // Error (pas de toString)
186
184
187
185
...Mais c'est généralement acceptable pour les tableaux associatifs.
188
186
189
-
Notez que la plupart des méthodes liées aux objets sont `Object.quelquechose(...)`, comme `Object.keys(obj)` - elles ne sont pas dans le prototype, elles continueront donc à travailler sur de tels objets:
187
+
Notez que la plupart des méthodes liées aux objets sont `Object.quelquechose(...)`, comme `Object.keys(obj)` - elles ne sont pas dans le prototype, elles continueront donc à travailler sur de tels objets:
- [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- renvoie le `[[Prototype]]` de `obj` (identique au getter `__proto__`).
215
213
- [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- définit le `[[Prototype]]` de `obj` à `proto` (identique au setter `__proto__`).
216
214
217
-
- Obtenir/définir le prototype en utilisant le getter/setter intégré `__proto__` n'est pas recommandé, c'est maintenant dans l'annexe B de la spécification.
215
+
- Obtenir/définir le prototype en utilisant le getter/setter intégré.`__proto__` n'est pas recommandé, il est maintenant dans l'annexe B de la spécification.
218
216
219
217
- Nous avons également couvert les objets sans prototype, créés avec `Object.create(null)` ou `{__proto__: null}`.
0 commit comments