Crockford a beaucoup fait pour populariser les bonnes techniques JavaScript. Ses prises de position sur les éléments clés du langage ont suscité de nombreuses discussions utiles. Cela dit, il y a beaucoup trop de gens qui prennent chaque proclamation de "mauvais" ou "nuisible" comme parole d'évangile, refusant de regarder au-delà de l'opinion d'un homme. C'est parfois un peu frustrant.
L'utilisation de la fonctionnalité fournie par le new
présente plusieurs avantages par rapport à la construction de chaque objet à partir de zéro :
-
Héritage des prototypes . Bien qu'elle soit souvent considérée avec un mélange de suspicion et de dérision par ceux qui sont habitués aux langages OO basés sur des classes, la technique d'héritage natif de JavaScript est un moyen simple et étonnamment efficace de réutiliser le code. Et le nouveau mot-clé est le moyen canonique (et le seul disponible sur toutes les plates-formes) de l'utiliser.
- Performance. Il s'agit d'un effet secondaire du point 1 : si je souhaite ajouter 10 méthodes à chaque objet que je crée, je dois pourrait juste écrire une fonction de création qui assigne manuellement chaque méthode à chaque nouvel objet... Ou bien, je pourrais les assigner à la fonction de création.
prototype
et utiliser new
pour supprimer les nouveaux objets. Non seulement cela est plus rapide (pas de code nécessaire pour chaque méthode du prototype), mais cela évite de gonfler chaque objet avec des propriétés distinctes pour chaque méthode. Sur les machines plus lentes (ou surtout sur les interpréteurs JS plus lents), lorsque de nombreux objets sont créés, cela peut représenter un gain de temps et de mémoire considérable.
Et oui, new
a un inconvénient crucial, habilement décrit par d'autres réponses : si vous oubliez de l'utiliser, votre code sera cassé sans avertissement. Heureusement, cet inconvénient est facilement atténué - il suffit d'ajouter un peu de code à la fonction elle-même :
function foo()
{
// if user accidentally omits the new keyword, this will
// silently correct the problem...
if ( !(this instanceof foo) )
return new foo();
// constructor logic follows...
}
Vous pouvez désormais bénéficier des avantages suivants new
sans avoir à se soucier des problèmes causés par une mauvaise utilisation accidentelle. Vous pouvez même ajouter une assertion à la vérification si l'idée d'un code cassé fonctionnant en silence vous dérange. Ou, comme un peu de commenté, utilisez le contrôle pour introduire une exception d'exécution :
if ( !(this instanceof arguments.callee) )
throw new Error("Constructor called as a function");
(Notez que ce snippet est capable d'éviter le codage en dur du nom de la fonction constructeur, car contrairement à l'exemple précédent, il n'a pas besoin d'instancier réellement l'objet - il peut donc être copié dans chaque fonction cible sans modification).
John Resig explique cette technique en détail dans son livre intitulé Instanciation de "classe" simple ainsi qu'un moyen d'intégrer ce comportement par défaut dans vos "classes". Cela vaut vraiment la peine de le lire... tout comme son prochain livre, Les secrets du ninja JavaScript qui trouve de l'or caché dans cette caractéristique et dans beaucoup d'autres caractéristiques "nuisibles" du langage JavaScript (la page chapitre sur with
est particulièrement instructif pour ceux d'entre nous qui ont d'abord considéré cette fonction très décriée comme un gadget).
97 votes
Il n'est PAS "mauvais" d'utiliser le nouveau mot-clé. Mais si vous l'oubliez, vous appellerez le constructeur d'objet comme une fonction normale. Si votre constructeur ne vérifie pas son contexte d'exécution, il ne remarquera pas que "this" pointe vers un objet différent (habituellement l'objet global) au lieu de la nouvelle instance. Par conséquent, votre constructeur ajoutera des propriétés et des méthodes à l'objet global (fenêtre). Si vous vérifiez toujours que 'this' est une instance de votre objet dans la fonction objet, alors vous n'aurez jamais ce problème.
5 votes
Je ne comprends pas. D'un côté Doug décourage l'utilisation de
new
. Mais quand vous regardez la bibliothèque YUI. Vous devez utilisernew
partout. Par exemplevar myDataSource = new Y.DataSource.IO({source:"./myScript.php"});
.2 votes
@aditya_gaur C'est parce que si vous avez besoin de l'initialisation d'un objet, vous devez bidouiller un
init
si vous utilisez la méthodeObject.create
et de l'appeler après. Il est beaucoup plus facile d'utilisernew
qui fait les deux, définit la chaîne de prototypes et appelle du code d'initialisation.71 votes
Je ne pense pas que cela aurait dû être fermé. Oui, il est probable que cela inspire un certain venin anti-fan Crockford, mais nous parlons ici d'un conseil populaire pour éviter une caractéristique majeure du langage. Le mécanisme qui fait que chaque objet JQuery ne pèse presque rien (en ce qui concerne la mémoire) implique l'utilisation du mot-clé "new". Préférez les méthodes d'usine à l'invocation constante de new, mais ne réduisez pas radicalement vos options architecturales et votre potentiel de performance en n'utilisant que des littéraux d'objet. Ils ont leur place et les constructeurs ont leur place. Il s'agit là d'un conseil totalement dépassé et minable.
1 votes
Rejeter un contexte d'exécution qui n'hérite pas de votre fonction objet n'est pas une approche judicieuse. Vous avez alors brisé des fonctionnalités critiques comme .call et .apply.
5 votes
TLDR : Utilisation
new
n'est pas dangereux. Omettrenew
est dangereux, et donc mauvais . Mais en ES5, vous pouvez utiliser Mode strict qui vous protège de ce danger et de bien d'autres.