Le new
mot clé en JavaScript peut être assez déroutant lors de sa première rencontre, car les gens ont tendance à penser que JavaScript n'est pas un langage de programmation orienté objet.
- Qu'Est-ce que c'est?
- Quels problèmes cela résout-il?
- Quand est-ce approprié et quand non?
javascript
new-operator
Alon Gubkin
la source
la source
Réponses:
Il fait 5 choses:
this
pointer la variable vers l'objet nouvellement créé.this
est mentionné.null
référence non- objet. Dans ce cas, cette référence d'objet est renvoyée à la place.Remarque: la fonction constructeur fait référence à la fonction après le
new
mot - clé, comme dansUne fois cela fait, si une propriété non définie du nouvel objet est demandée, le script vérifiera plutôt l'objet [[prototype]] de l' objet pour la propriété. C'est ainsi que vous pouvez obtenir quelque chose de similaire à l'héritage de classe traditionnel en JavaScript.
La partie la plus difficile à ce sujet est le point numéro 2. Chaque objet (y compris les fonctions) possède cette propriété interne appelée [[prototype]] . Il ne peut être défini qu'au moment de la création de l'objet, soit avec new , avec Object.create , soit en fonction du littéral (fonctions par défaut à Function.prototype, nombres à Number.prototype, etc.). Il ne peut être lu qu'avec Object.getPrototypeOf (someObject) . Il n'existe aucun autre moyen de définir ou de lire cette valeur.
Les fonctions, en plus de la propriété cachée [[prototype]] , ont également une propriété appelée prototype , et c'est à cela que vous pouvez accéder et la modifier pour fournir des propriétés et des méthodes héritées aux objets que vous créez.
Voici un exemple:
C'est comme l'héritage de classe car maintenant, tous les objets que vous créez en utilisant
new ObjMaker()
sembleront également avoir hérité de la propriété «b».Si vous voulez quelque chose comme une sous-classe, alors vous faites ceci:
J'ai lu une tonne d'ordures sur ce sujet avant de retrouver enfin cette page , où cela s'explique très bien avec de jolis diagrammes.
la source
ObjMaker
est définie comme une fonction qui renvoie une valeur?new
existe afin que vous n'ayez pas à écrire de méthodes d'usine pour construire / copier des fonctions / objets. Cela signifie, "Copiez ceci, en le faisant exactement comme sa 'classe' parent; faites-le efficacement et correctement; et stockez les informations d'héritage qui ne sont accessibles qu'à moi, JS, en interne". Pour ce faire, il modifie l'interne autrement inaccessibleprototype
du nouvel objet pour encapsuler de manière opaque les membres hérités, imitant les chaînes d'héritage OO classiques (qui ne sont pas modifiables au moment de l'exécution). Vous pouvez simuler cela sansnew
, mais l'héritage sera modifiable à l'exécution. Bien? Mauvais? Dépend de vous.Notice that this pattern is deprecated!
. Quel est le modèle de mise à jour correct pour définir le prototype d'une classe?Supposons que vous ayez cette fonction:
Si vous appelez cela comme une fonction autonome comme ceci:
L'exécution de cette fonction ajoutera deux propriétés à l'
window
objet (A
etB
). Il l'ajoute auwindow
carwindow
est l'objet qui a appelé la fonction lorsque vous l'exécutez comme ça, etthis
dans une fonction se trouve l'objet qui a appelé la fonction. En Javascript au moins.Maintenant, appelez-le comme ceci avec
new
:Ce qui se passe lorsque vous ajoutez
new
à un appel de fonction, c'est qu'un nouvel objet est créé (justevar bar = new Object()
) et que l'this
intérieur de la fonction pointe vers le nouveau queObject
vous venez de créer, au lieu de l'objet qui a appelé la fonction. Il enbar
est de même d'un objet avec les propriétésA
etB
. Toute fonction peut être un constructeur, cela n'a tout simplement pas toujours de sens.la source
window
implicitement une méthode . Même dans une fermeture, même si anonyme. Cependant, dans l'exemple, il s'agit d'une simple invocation de méthode sur la fenêtre:Foo();
=>[default context].Foo();
=>window.Foo();
. Dans cette expressionwindow
est le contexte (pas seulement l' appelant , ce qui n'a pas d'importance).En plus de la réponse de Daniel Howard, voici ce que
new
fait (ou du moins semble faire):Tandis que
est équivalent à
la source
func.prototype
de l'êtrenull
? Pourriez-vous nous en dire un peu plus à ce sujet?A.prototype = null;
Dans ce cas, celanew A()
se traduira par un objet, c'est le prototype interne qui pointe vers l'Object
objet: jsfiddle.net/Mk42ZObject(ret) === ret
.typeof
test permet simplement de comprendre plus facilement ce qui se passe dans les coulisses.Pour que les débutants le comprennent mieux
essayez le code suivant dans la console du navigateur.
Vous pouvez maintenant lire la réponse du wiki de la communauté :)
la source
return this;
donne le même résultat.Il est utilisé exactement pour cela. Vous définissez un constructeur de fonction comme ceci:
Cependant, l'avantage supplémentaire d'ECMAScript est que vous pouvez l'étendre avec la
.prototype
propriété, afin que nous puissions faire quelque chose comme ...Tous les objets créés à partir de ce constructeur auront désormais un en
getName
raison de la chaîne de prototype à laquelle ils ont accès.la source
class
mot-clé mais vous pouvez à peu près faire la même chose.JavaScript est un langage de programmation orienté objet et il est utilisé exactement pour créer des instances. Il est basé sur un prototype plutôt que sur une classe, mais cela ne signifie pas qu'il n'est pas orienté objet.
la source
Javascript est un langage de programmation dynamique qui prend en charge le paradigme de programmation orienté objet, et il utilise utilisé pour créer de nouvelles instances d'objet.
Les classes ne sont pas nécessaires pour les objets - Javascript est un langage basé sur un prototype .
la source
Il existe déjà de très bonnes réponses, mais j'en publie une nouvelle pour souligner mon observation sur le cas III ci-dessous sur ce qui se passe lorsque vous avez une déclaration de retour explicite dans une fonction que vous êtes en
new
train de créer. Jetez un œil aux cas ci-dessous:Cas I :
Ci-dessus est un cas simple d'appel de la fonction anonyme pointée par
Foo
. Lorsque vous appelez cette fonction, elle revientundefined
. Puisqu'il n'y a pas d'instruction de retour explicite, l'interpréteur JavaScript insère avec force unereturn undefined;
instruction à la fin de la fonction. Ici , la fenêtre est l'objet d'invocation (contextuellethis
) qui obtient de nouveauxA
etB
propriétés.Cas II :
Ici, l'interpréteur JavaScript voyant le
new
mot - clé crée un nouvel objet qui agit comme l'objet d'invocation (contextuelthis
) de la fonction anonyme pointée parFoo
. Dans ce casA
etB
devenez propriétés sur l'objet nouvellement créé (à la place de l'objet fenêtre). Étant donné que vous n'avez aucune instruction de retour explicite, l'interpréteur JavaScript insère avec force une instruction de retour pour renvoyer le nouvel objet créé en raison de l'utilisation dunew
mot - clé.Cas III :
Ici encore, l'interpréteur JavaScript voyant le
new
mot - clé crée un nouvel objet qui agit comme l'objet d'invocation (contextuelthis
) de la fonction anonyme pointée parFoo
. Encore une fois,A
etB
devenez des propriétés sur l'objet nouvellement créé. Mais cette fois, vous avez une déclaration de retour explicite, donc l'interpréteur JavaScript ne fera rien de lui-même.La chose à noter dans le cas III est que l'objet créé en raison d'un
new
mot clé s'est perdu de votre radar.bar
pointe en fait vers un objet complètement différent qui n'est pas celui créé par l'interpréteur JavaScript à cause dunew
mot-clé.Citant David Flanagan de JavaScripit: The Definitive Guide (6th Edition), Ch. 4, page n ° 62:
--- Informations supplémentaires ---
Les fonctions utilisées dans l'extrait de code des cas ci-dessus ont des noms spéciaux dans le monde JS comme ci-dessous:
Cas I et II - Fonction constructeur
Cas III - Fonction d'usine. Les fonctions d'usine ne doivent pas être utilisées avec le
new
mot-clé que j'ai fait pour expliquer le concept dans le thread actuel.Vous pouvez lire sur la différence entre eux dans ce fil.
la source
parfois le code est plus facile que les mots:
pour moi, tant que je ne fais pas de prototype, j'utilise le style de func2 car cela me donne un peu plus de flexibilité à l'intérieur et à l'extérieur de la fonction.
la source
B1 = new func2(2);
<- Pourquoi cela n'aura pasB1.y
?Le
new
mot-clé modifie le contexte dans lequel la fonction est exécutée et renvoie un pointeur vers ce contexte.Lorsque vous n'utilisez pas le
new
mot clé, le contexte sous lequel la fonctionVehicle()
s'exécute est le même contexte à partir duquel vous appelez laVehicle
fonction. Lethis
mot-clé fera référence au même contexte. Lorsque vous utiliseznew Vehicle()
, un nouveau contexte est créé afin que le mot-cléthis
à l'intérieur de la fonction fasse référence au nouveau contexte. Ce que vous obtenez en retour, c'est le contexte nouvellement créé.la source
Le
new
mot-clé sert à créer de nouvelles instances d'objets. Et oui, javascript est un langage de programmation dynamique, qui prend en charge le paradigme de programmation orienté objet. La convention concernant la dénomination des objets est de toujours utiliser des majuscules pour les objets censés être instanciés par le nouveau mot clé.la source
Sommaire:
Le
new
mot-clé est utilisé en javascript pour créer un objet à partir d'une fonction constructeur. Lenew
mot-clé doit être placé avant l'appel de la fonction constructeur et fera les choses suivantes:this
mot - clé à l'objet nouvellement créé et exécute la fonction constructeurExemple:
Que se passe-t-il exactement:
const doggie
dit: Nous avons besoin de mémoire pour déclarer une variable.=
dit: Nous allons initialiser cette variable avec l'expression après le=
new Dog(12)
. Le moteur JS voit le nouveau mot-clé, crée un nouvel objet et définit le prototype sur Dog.prototypethis
valeur définie sur le nouvel objet. C'est à cette étape que l'âge est attribué au nouvel objet toutou créé.la source
Le
new
mot-clé crée des instances d'objets en utilisant des fonctions comme constructeur. Par exemple:Les instances héritent de la
prototype
fonction constructeur. Donc, étant donné l'exemple ci-dessus ...la source
Eh bien, JavaScript per si peut différer considérablement d'une plate-forme à l'autre, car il s'agit toujours d'une implémentation de la spécification originale EcmaScript.
Dans tous les cas, indépendamment de l'implémentation, toutes les implémentations JavaScript qui suivent le droit de spécification EcmaScript, vous donneront un langage orienté objet. Selon la norme ES:
Alors maintenant que nous avons convenu que JavaScript est une implémentation d'EcmaScript et donc c'est un langage orienté objet. La définition de l'
new
opération dans n'importe quel langage orienté objet, dit qu'un tel mot clé est utilisé pour créer une instance d'objet à partir d'une classe d'un certain type (y compris les types anonymes, dans des cas comme C #).En EcmaScript, nous n'utilisons pas de classes, comme vous pouvez le lire dans les spécifications:
la source