50 votes

Pourquoi éviter de créer des objets en JavaScript?

Je suis un tutoriel JavaScript sur W3Schools. En lisant presque sur chaque page, ils indiquent à l’utilisateur «d’éviter de créer des objets» et d’utiliser plutôt des types de données primitifs. Ils en donnent la raison car "le code devient difficile à comprendre ou la vitesse d'exécution diminue si les objets sont utilisés". Est-il vrai que nous devrions éviter de créer des objets en JavaScript?

Par exemple:

 var value = new Number(1);  // Avoid this
var value = 1;              // do something like this instead.
 

107voto

T.J. Crowder Points 285826

La déclaration "d'éviter de créer des objets" est absurde en JavaScript, ce qui a des objets partout et est l'un des la plupart des langages orientés objet dans l'existence. Mais "éviter de créer des versions d'objets de primitives", qui est ce que le code que vous citez, est valide. C'est, d'éviter new String, new Number, et new Boolean.

JavaScript a la fois primitive et les versions d'objets de chaînes de caractères, nombres, et les booléens. Il n'y a presque jamais aucune raison de créer la version de l'objet de l'un d'eux de manière explicite, et cela peut en effet conduire à la confusion; voir les commentaires en ligne:

var s1, s2, n1, n2;

// These are false because with ===, an object is never equal to a non-object
s1 = new String("hi");
s2 = "hi";
console.log(s1 === s2); // false
n1 = new Number(42);
n2 = 42;
console.log(n1 === n2); // also false

// These are false because even with ==, two *different* objects are never equal
// (even if they're equivalent)
s1 = new String("what the...");
s2 = new String("what the...");
console.log(s1 == s2);  // also false
n1 = new Number(42);
n2 = new Number(42);
console.log(n1 == n2);  // also false

L'objet de versions de chaînes de caractères, nombres, et les booléens largement existent pour permettre à des méthodes sur des primitives pour être fournis en utilisant le même mécanisme qui fournit des méthodes pour les types d'objet. Lorsque vous ne

console.log("foo".toUpperCase()); // "FOO"

un objet temporaire est créé pour la primitive de la chaîne "foo", puis l' toUpperCase propriété est en lecture à partir de cet objet. Depuis l'objet hérite String.prototype, il a toUpperCase et tout est bien. Une fois l'opération terminée, l'objet temporaire est jeté (à moins que quelque chose maintient une référence vers elle, mais rien n'est et ne peut rien avec toUpperCase, vous devez ajouter une méthode à l' String.prototype renvoyé l'objet dans l'ordre pour qu'il soit maintenu autour).

11voto

M. M. Points 157

Il change la manière intuitive les opérateurs se comportent avec des nombres, des chaînes et des booléens:

  • la comparaison stricte (===) des pauses lorsque l'un des nombres est construit, afin 42 === 42 est vraie, alors 42 === new Number(42) n'est pas,
  • le résumé de la comparaison (==) des pauses lorsque les deux nombres sont des objets, de sorte 42 == new Number(42) est vraie, alors new Number(42) == new Number(42) n'est pas,
  • l' typeof opérateur donne des résultats différents lorsqu'un numéro est construit, afin typeof(42) est number, mais typeof(new Number(42)) est object,
  • lors de la conversion en booléen, 0 est faux, mais new Number(0) est vrai, les deux auront un comportement différent:

var a = 0;
if (a)
  console.log("not zero");
else
  console.log("zero!");     // "zero!"

var b = new Number(0);
if (b)
  console.log("not zero");     // "not zero"
else
  console.log("zero!");

Donc, évitez new Number, new String et new Boolean.

En dehors de cela, il y a la question de l'utiliser ou non new avec des constructeurs. Il est le résultat de plusieurs faits:

  • en JS, un constructeur est une fonction régulière, à l'aide de this.foo de la syntaxe pour ajouter de nouvelles propriétés et méthodes;
  • lorsqu'il est invoqué sans l' new mot-clé, this devient l'objet global, conduisant à des effets secondaires.

Comme un résultat, une petite erreur peut avoir des effets catastrophiques:

color = "blue";

var Fruit = function(color) {
  this.color = color;
  return this;
};

var apple = new Fruit("green");

console.log(apple.color);       // "green"  --  okay

console.log(color);             // "blue"  --  okay

var banana = Fruit("yellow");

console.log(banana.color);      // "yellow"  --  okay

console.log(color);             // "yellow"  --  wait, what?

console.log(banana.apple);      // "{ color: 'green' }"  --  what??

console.log(banana.document);   // "{ location: [Getter/Setter] }"  --  what???

(C'est pourquoi certaines personnes ont recours à l'ajout explicite vérifie dans le constructeur, ou à l'aide de fermetures à la place. Mais ça c'est une autre histoire.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X