131 votes

Pourquoi fait ! {} [true] avoir la valeur true en JavaScript ?

est et doivent être .

Alors pourquoi fait sont évaluées à ?

172voto

Frédéric Hamidi Points 123646

Je crois que c'est à cause de la plaine {}[true] est analysée comme une instruction vide (bloc n'est pas un objet littéral), suivie par un tableau contenant true, ce qui est true.

D'autre part, l'application de l' ! opérateur fait l'analyseur interpréter {} comme un objet littéral, donc la suite {}[true] devient membre de l'accès que les retours undefined, et !{}[true] est en effet true ( !undefined est true).

44voto

dooxe Points 946

Parce que ne retourne pas , mais , et est évaluée comme `` :

http://jsfiddle.net/67GEu/

27voto

Games Brainiac Points 13322

Parce que

{}[true]

évalue undefined, et !undefined est true.

@Schlingel:

true est utilisé comme clé et {} de hachage de la carte. Il n'existe pas une propriété avec la touche true on en revient donc undefined. Pas undefined est true, comme prévu.

Session de Console (Node.js [0.10.17]):

> {}[true]
undefined
> !{}[true]
true
> [true]
[ true ]
> ![true]
false
>

Toutefois, dans le Google Chrome console:

> !{}[true]
true

Donc, pas d'incohérences. Vous êtes probablement en utilisant une ancienne version de la VM JavaScript. Pour ceux qui ont besoin de davantage de preuves:

Enter image description here

Mise à JOUR

Avec Firefox, il évalue aussi pour true:

Enter image description here

23voto

Spudley Points 85371

La raison de la confusion est le résultat d'une incompréhension de votre première affirmation:

{}[true] est [true]

Ce que vous voyez lorsque vous exécutez elle est le résultat d'une ambiguïté. Javascript a défini un ensemble de règles sur la manière de gérer les ambiguïtés de ce genre, et dans ce cas, il se casse ce que vous voyez comme un signle déclaration en deux états distincts.

Donc, Javascript voit le code ci-dessus que les deux états distincts: tout d'Abord, il y a un {}, et puis il est entièrement distincte [true]. La deuxième instruction est ce qui vous donne le résultat en [true]. La première instruction {} est effetively totalement ignoré.

Vous pouvez le prouver en faisant ce qui suit:

({}[true])

ie enveloppant le tout entre parenthèses pour forcer l'interprète de le lire comme une seule instruction.

Maintenant, vous allez voir que la valeur réelle de votre déclaration est - undefined. (ce sera aussi pour nous aider plus tard à comprendre la partie suivante)

Maintenant, nous savons que la première partie de votre question est un leurre, donc, nous allons passer à la dernière partie de la question:

Alors, pourquoi ne !{}[true] true?

Ici, nous avons la même déclaration, mais avec un ! ajouté à l'avant.

Dans ce cas, le Javascript les règles de dire qu'il évalue la chose entière comme une seule instruction.

Se référer à ce qui s'est passé lorsque nous avons terminé la déclaration précédente entre parenthèses; nous avons eu undefined. Cette fois, nous sommes en mesure de faire la même chose, mais en mettant un ! , en face de lui. Ainsi, votre code peut être simplifié comme !undefined, ce qui est true.

J'espère que ça explique un peu.

C'est un complexe bête, mais la leçon à tirer ici est d'utiliser des crochets autour de vos relevés lors de l'évaluation dans la console, pour éviter de fausser les résultats de ce genre.

14voto

Ionică Bizău Points 14484

{}[true] est undefined. À trouver que d'écrire ceci:

a = {};
a[true] === undefined // true

ou tout simplement:

({})[true] === undefined // true

Nous savons qu' !undefined est true.


De @Benjamin Gruenbaum réponse:

Chrome dveloper les outils suivants:

  try {
      if (injectCommandLineAPI && inspectedWindow.console) {
          inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
          expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}";
      }
      var result = evalFunction.call(object, expression);
      if (objectGroup === "console")
          this._lastResult = result;
      return result;
  } 
  finally {
      if (injectCommandLineAPI && inspectedWindow.console)
          delete inspectedWindow.console._commandLineAPI;
  }

Donc, fondamentalement, il effectue un call sur l'objet avec l'expression. L'expression:

with ((window && window.console && window.console._commandLineAPI) || {}) {
    {}+{};// <-- This is your code
}

Donc, comme vous pouvez le voir, l'expression est effectuée directement, sans l'habillage de la parenthèse.

Plus d'informations peuvent être trouvées à cette question.

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