Comment une chaîne JavaScript n'est-elle pas un objet?

Ce n'est pas l'installation d'une blague, je demande vraiment.

Douglas Crockford aime bien dire que dans le langage prototypique javascript orienté objet, il n'y a pas besoin de new .

Il explique que la new été simplement ajoutée pour donner aux gens venant des langages de programmation orientés objet classés (c'est-à-dire " classiques ") un certain niveau de confort:

JavaScript, nous ne sommes pas trop new Ya

JavaScript est un langage prototypique, mais il a un new opérateur qui essaie de faire ressembler à une langue classique. Cela tend à confondre les programmeurs, entraînant des modèles de programmation problématiques.

Vous n'avez jamais besoin d'utiliser new Object() dans JavaScript. Utilisez plutôt l'objet literal {} .

D'accord, bien:

  • new mauvais
  • {} Bon

Mais alors, le commentateur Vítor De Araújo a souligné que les deux ne sont pas les mêmes . Il donne un exemple montrant qu'une string n'est pas comme un object :

Un objet de chaîne et une valeur de chaîne ne sont pas la même chose:

 js> p = "Foo" Foo js> p.weight = 42 42 js> p.weight // Returns undefined js> q = new String("Foo") Foo js> q.weight = 42 42 js> q.weight 42 

La valeur de chaîne ne peut pas avoir de nouvelles propriétés. La même chose est valable pour d'autres types.

Qu'est-ce qui se passe ici qu'une string n'est pas un object ? Est-ce que je suis confus javascript avec d'autres langues, où tout est un objet?

"Tout est un objet" … c'est l'une des grandes idées fausses qui existent autour de la langue.

Pas tout est un objet, il y a ce que nous appelons les valeurs primitives , qui sont la chaîne, le nombre, le booléen, le null et l'indéfini.

C'est vrai, une chaîne est une valeur primitive , mais vous pouvez accéder à toutes les méthodes héritées de String.prototype comme s'il s'agissait d'un objet.

Les opérateurs d'accès de propriété (le point et la notation de bracket), transmettent temporairement la valeur de chaîne à un objet String, pour pouvoir accéder à ces méthodes, par exemple:

 "ab".charAt(1); // "b" 

Ce qui se passe derrière les scènes est quelque chose comme ceci:

 new String("ab").charAt(1); // "b", temporal conversion ToObject 

Comme pour les autres valeurs primitives, telles que Boolean , et Number , il y a des wrappers d'objets , qui sont simplement des objets qui contiennent la valeur primitive, comme dans votre exemple:

 var strObj = new String(""); strObj.prop = "foo"; typeof strObj; // "object" typeof strObj.prop; // "string" 

Alors qu'avec une primitive:

 var strValue = ""; strValue.prop = "foo"; typeof strValue; // "string" typeof strValue.prop; // "undefined" 

Et cela se produit parce que, à nouveau, l'accessoire de propriété sur la deuxième ligne ci-dessus crée un nouvel objet temporel, comme suit:

 var strValue = ""; new String(strValue).prop = "foo"; // a new object which is discarded //...