Pourquoi deux hamsters sont rassasiés ?
Nous avons deux hamsters: speedy
et lazy
héritant de l’objet général hamster
.
Lorsque nous nourrissons l’un d’eux, l’autre est également rassasié. Pourquoi ? Comment y remédier ?
let
hamster =
{
stomach
:
[
]
,
eat
(
food
)
{
this
.
stomach.
push
(
food)
;
}
}
;
let
speedy =
{
__proto__
:
hamster
}
;
let
lazy =
{
__proto__
:
hamster
}
;
// Celui-ci a trouvé la nourriture
speedy.
eat
(
"apple"
)
;
alert
(
speedy.
stomach )
;
// apple
// Celui-ci l'a aussi, pourquoi ? Merci de corriger cela.
alert
(
lazy.
stomach )
;
// apple
Examinons attentivement ce qui se passe dans l’appel speedy.eat("apple")
.
-
La méthode
speedy.eat
se trouve dans le prototype (=hamster
), puis exécutée avecthis=speedy
(l’objet avant le point). -
Ensuite,
this.stomach.push()
doit trouver la propriétéstomach
et appelerpush
dessus. Il cherchestomach
dansthis
(=speedy
), mais rien n’est trouvé. -
Ensuite, il suit la chaîne de prototypes et trouve
stomach
danshamster
. -
Ensuite, il appelle
push
dessus, en ajoutant la nourriture dans stomach du prototype.
Tous les hamsters partagent donc un seul estomac!
Tant pour lazy.stomach.push(...)
et speedy.stomach.push()
, la propriété stomach
se trouve dans le prototype (comme il est pas dans l’objet lui-même), alors les nouvelles données sont poussé dedans.
Veuillez noter qu’une telle chose ne se produit pas dans le cas d’une simple affectation this.stomach=
:
let
hamster =
{
stomach
:
[
]
,
eat
(
food
)
{
// assigner à this.stomach au lieu de this.stomach.push
this
.
stomach =
[
food]
;
}
}
;
let
speedy =
{
__proto__
:
hamster
}
;
let
lazy =
{
__proto__
:
hamster
}
;
// Speedy a trouvé la nourriture
speedy.
eat
(
"apple"
)
;
alert
(
speedy.
stomach )
;
// apple
// L'estomac de Lazy est vide
alert
(
lazy.
stomach )
;
// <rien>
Maintenant, tout fonctionne bien, car this.stomach=
n’effectue pas de recherche de stomach
. La valeur est écrite directement dans l’objet this
.
Nous pouvons également éviter le problème en nous assurant que chaque hamster a son propre stomach :
let
hamster =
{
stomach
:
[
]
,
eat
(
food
)
{
this
.
stomach.
push
(
food)
;
}
}
;
let
speedy =
{
__proto__
:
hamster,
stomach
:
[
]
}
;
let
lazy =
{
__proto__
:
hamster,
stomach
:
[
]
}
;
// Speedy a trouvé la nourriture
speedy.
eat
(
"apple"
)
;
alert
(
speedy.
stomach )
;
// apple
// L'estomac de Lazy est vide
alert
(
lazy.
stomach )
;
// <rien>
En tant que solution commune, toutes les propriétés qui décrivent l’état d’un objet particulier, comme stomach
ci-dessus, devraient être écrits dans cet objet. Cela empêche de tels problèmes.