37 votes

Pourquoi existe-t-il deux types de chaînes JavaScript?

Celui-ci m'a poignardé dur. Je ne sais pas si c'est le cas avec tous les navigateurs (je n'ai pas d'autres compétente navigateur afin de le tester), mais au moins, Firefox a deux types d'objets string.

Ouvrir le Firebugs console et essayez ce qui suit:

>>> "a"
"a"
>>> new String("a")
String { 0="a"}

Comme vous pouvez l'observer, Firefox friandises new String("a") et "a" différemment. Sinon, toutefois, les deux types de chaînes semblent se comporter de la même. Il est, par exemple, la preuve que les deux utilisent le même prototype de l'objet:

>>> String.prototype.log = function() { console.log("Logged string: " + this); }
function()
>>> "hello world".log()
Logged string: hello world
>>> new String("hello world").log()
Logged string: hello world

Donc, apparemment, les deux sont les mêmes. C'est, jusqu'à ce que vous demandez pour le type.

>>> typeof("a")
"string"
>>> typeof(new String("a"))
"object"

On peut aussi remarquer que lors de l' this est une chaîne de caractères, il est toujours l'objet de formulaire:

>>> var identity = function() { return this }
>>> identity.call("a")
String { 0="a"}
>>> identity.call(new String("a"))
String { 0="a"}

Pour aller un peu plus loin, nous pouvons voir que le non-objet de représentation de chaîne ne prend pas en charge toutes les propriétés supplémentaires, mais l'objet chaîne n':

>>> var a = "a"
>>> var b = new String("b")
>>> a.bar = 4
4
>>> b.bar = 4
4
>>> a.bar
undefined
>>> b.bar
4

Aussi, fait amusant! Vous pouvez activer un objet de type string dans un non-objet string à l'aide de l' toString() fonction de:

>>> new String("foo").toString()
"foo"

Jamais pensé qu'il pourrait être utile de communiquer String.toString()! De toute façon.

Donc, toutes ces expériences soulèvent la question: pourquoi il y a deux types de chaînes de caractères en JavaScript?


Les commentaires montrent que cela est également le cas pour toutes les primitives JavaScript type (nombre et bool inclus).

14voto

Kelly Points 8780

Il existe deux types de chaînes de caractères en Javascript -- les chaînes littérales et des objets String. Ils ne se comportent un peu différemment. La principale différence entre les deux est que vous pouvez ajouter d'autres méthodes et propriétés d'un objet de type String. Par exemple:

var strObj = new String("object mode");
strObj.string_mode = "object"
strObj.get_string_mode = function() { return this.string_mode; }

// this converts it from an Object to a primitive string:
str = strObj.toString();

Un littéral de chaîne est juste temporairement cast d'un objet de type String pour effectuer l'une des méthodes de base.

Les mêmes types de concepts s'appliquent à d'autres types de données, trop. Voici plus d'informations sur les types de données primitifs et les objets.

MODIFIER

Comme indiqué dans les commentaires, les littéraux de chaîne ne sont pas primitives chaînes, plutôt une "constante littérale dont le type est une primitive intégré [string] valeur", citant cette source.

2voto

Raynos Points 82706

Votre comparaison de valeurs de chaîne à des objets de chaîne.

"a" est une valeur de chaîne.

"a" === "a"; // true

new String("a") est un objet chaîne.

new String("a") === new String("a"); // false

Il y a deux cordes. "a" n'obtient que la valeur de chaîne "a", où new String("a") crée un nouvel objet chaîne qui a en interne la valeur de chaîne "a"

0voto

Juan Mendes Points 31678

Une autre chose importante à retenir est la suivante:

typeof "my-string" // "string"
typeof String('my-string') // 'string'
typeof new String("my-string") // "object". 

Par conséquent, lors de la vérification d'un argument ou d'une variable est une chaîne de caractères que vous devez faire au moins les éléments suivants.

function isString(arg) {
  if (!arg) {
    return false;
  }
  return typeof arg == "string" || arg.constructor == String;
}

La fonction ci-dessus va encore échouer si vous passez une Chaîne de caractères de l'objet à partir d'un autre frame/iframe. C'est:

frames[0].myStringVar.constructor != frames[1].myStringVar.constructor

C'est parce que le constructeur String est différent pour chaque fenêtre de contexte. Par conséquent, toute épreuve isString de la méthode

function isString(obj) {
   return Object.prototype.toString.call(obj) == "[object String]";
}

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