2010-01-07 5 views
3

Essayer d'obtenir mes fondamentaux JavaSscript forts. Donc la question concerne les littéraux de chaînes. Ne sont-ils pas Objects? Si votre réponse est «oui» alors ma question est pourquoi est instanceof retournant false?Les objets littéraux de chaîne sont-ils ou non?

> var s = new String 
> s.constructor.toString() 
function String() { [native code] } 

> typeof s 
object 

> s instanceof String 
true 

> s instanceof Object 
true 

> s instanceof Number 
false 

Jusqu'ici tout va bien.

> typeof 'c' 
string 

> 'c' instanceof Object 
false 

> 'c' instanceof String 
false 

> 'c'.length 
1 

> 'c'.charAt(0) 
c 

> 'c'.constructor.toString() 
function String() { [native code] } 
+3

Je dirais que cette question est un doublon de http://stackoverflow.com/questions/203739/why-does-instanceof-return-false-for-some-literals aussi, mais la réponse sur cette copie est plate faux (souligné dans le commentaire à la réponse acceptée là-bas). –

+0

@Cresent Fresh - vous avez absolument raison! 3 .toString() ou 3..toString() fonctionne (btw, que se passe-t-il avec ces deux points?) – Murali

+0

Quand j'ai essayé avec 3 points, il obtient une erreur étrange! 3 ... toString() TypeError sur la ligne 1: Méthode interne des descendants XML appelée incompatible Number – Murali

Répondre

5

littéraux de chaîne sont primitives (String values), String objects peuvent être créés avec le String constructor dans une expression new:

"foo" instanceof String // false 

new String("foo") instanceof String // true 

Edit: Quelque chose qui semble être déroutant (en regardant la réponse acceptée here), est que vous pouvez toujours accéder aux propriétés définies sur le objets prototypes des valeurs primitives, par exemple:

"foo".indexOf == String.prototype.indexOf // true 
"foo".match == String.prototype.match // true 
String.prototype.test = true; 
"foo".test // true 
true.toString == Boolean.prototype.toString 
(3).toFixed == Number.prototype.toFixed // true 
// etc... 

La raison qui repose sur la Property Accessors, la notation de point . et la notation support [].

Donnons un coup d'oeil à l'algorithme dans la spécification ECMA-262:

Le MemberExpression de production: MemberExpression [expression] (. Ou MemberExpression Identifier) ​​est évaluée comme suit:

  1. Évaluer MemberExpression .

  2. Appelez GetValue(Result(1)).

  3. Évaluer l'expression.

  4. Appelez GetValue(Result(3)).

  5. Appelez ToObject(Result(2)).

  6. Appelez ToString(Result(4)).

  7. Renvoie une valeur de type Référence dont l'objet de base est Result (5) et dont le nom de propriété est Result(6).

Dans le Étape 5, l'opérateur interne ToObject type convertit le MemberExpression à l'objet, en fonction de son type.

Les primitives sont converties en objets sans le remarquer, et c'est pourquoi vous pouvez accéder aux propriétés définies sur le prototype.

0

Grande explication de ce here. Copié pour référence ci-dessous.


C'est parce que ces choses sont primitives, et à moins qu'ils ne doivent être utilisés comme des objets (lorsque vous appelez des méthodes sur eux, par exemple), ils restent. La seule fois où ils "deviennent" des objets, c'est quand ils doivent être emballés. Si vous êtes familier avec le concept de "boxe" dans .NET, alors pensez-y de cette façon.

Voici un exemple - jetez un oeil à ce code:

Number.prototype.times = function(func) { 
    for(var index = 1; index <= this; index++) { 
     func(index); 
    } 
}; 

Ainsi, le code suivant échouera:

3.times(print); // assume 'print' writes to standard out 

3, par lui-même est une primitive. Cela dit, ce qui suit fonctionnera:

(3).times(print); // assume 'print' writes to standard out 

qui afficherait les numéros 1, 2 et 3. En raison de la parenthèse, l'interpréteur JavaScript sera temporairement envelopper le 3 primitif dans un objet Number, appelez la méthode, puis garbage collecter l'objet car il n'est plus nécessaire.

Quoi qu'il en soit, une discussion complète de ce qui peut être trouvé dans "JavaScript: The Definitive Guide."

+0

Trouvé. 3.13. Objets Wrapper Primitive Datatype. Merci encore. – Murali

+4

Er, no. '3times' échoue parce que c'est une erreur de syntaxe: l'analyseur permet à' 3. 'd'être une décimale. Le '()' supprime simplement l'ambiguïté, rien à voir avec "boxe". Essayez-le: '3 .times 'fonctionne, tout comme' 3.x ', tout comme' 3. .fois. –

+0

@Crescent, édité ma réponse pour rendre ceci moins confus, sur pourquoi vous pouvez accéder aux propriétés de Number.prototype d'une primitive de nombre comme dans cet exemple – CMS

Questions connexes