Aidez-moi à comprendre la boucle "while" dans cet extrait de JavaScript

J'ai vu un extrait comme celui-ci pour détecter IE dans JavaScript en utilisant des commentaires conditionnels.

var ie = (function(){ var undef, v = 3, div = document.createElement('div'); // the while loop is used without an associated block: {} // so, only the condition within the () is executed. // semicolons arent allowed within the condition, // so a comma is used to stand in for one // basically allowing the two separate statements // to be evaluated sequentially. while ( div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->', div.getElementsByTagName('i')[0] ); // each time it's evaluated, v gets incremented and // tossed into the DOM as a conditional comment // the i element is then a child of the div. // the return value of the getEBTN call is used as // the final condition expression // if there is an i element (the IE conditional // succeeded), then getEBTN's return is truthy // and the loop continues until there is no // more i elements. // In other words: ** MAGIC** return v > 4 ? v : undef; }()); 

Ce qui précède est la version documentée (et légèrement améliorée) de Paul Irish sur un extrait de James Padolsey . Je publie la version commentée pour vous faire savoir que je pourrais avoir besoin d'une explication plus simple si quelqu'un peut.

J'aimerais vraiment savoir ce qui se passe dans la boucle while . Je ne comprends pas cela.

(En supposant que je ne l'ai pas dérangé horriblement), la boucle while équivaut à ce qui suit:

 var elt; do { v++; div.innerHTML = '<!--[if gt IE ' + v + ']><i></i><![endif]-->' elt = div.getElementsByTagName('i')[0]; } (while elt); 

Mdc ou tout bon couvre-t-il ce problème (stmt1, stmt2).

Voici ce que MDC dit à propos de:

 while (condition) statement 

condition
Une expression évaluée avant chaque passage dans la boucle. Si cette condition est évaluée comme true , l' statement est exécutée. Lorsque la condition est évaluée comme false , l'exécution continue avec l'instruction après la boucle while.

Nous pouvons trouver exactement ce qu'est une expression en JavaScript de MDC:

Une expression est un ensemble valide de littéraux, de variables, d'opérateurs et d'expressions qui évalue à une seule valeur; La valeur peut être un nombre, une chaîne ou une valeur logique.

Conceptuellement, il existe deux types d'expressions: ceux qui attribuent une valeur à une variable et ceux qui ont simplement une valeur. Par exemple, l'expression x = 7 est une expression qui attribue x la valeur sept. Cette expression elle-même évalue à sept. De telles expressions utilisent des opérateurs d'affectation . D'autre part, l'expression 3 + 4 évalue simplement à sept; Il n'effectue pas d'affectation. Les opérateurs utilisés dans ces expressions sont appelés simplement opérateurs .

Si vous vous sentez courageux, vous pouvez également consulter la spécification linguistique ECMA-262 , en particulier les sections suivantes:

  • 11 Expressions, en particulier 11.14 Comma Operator ( , )
  • 12.6.2 L'énoncé While

Désolé, je ne peux pas fournir de liens directs car tout se trouve dans un PDF.

v stocke le numéro de version IE. Il est initialisé à 3, de sorte que la boucle crée des chaînes comme les suivantes à chaque itération:

 // v = 3 <!--[if gt IE 4]><i></i><![endif]--> // v = 4 <!--[if gt IE 5]><i></i><![endif]--> 

Si vous êtes confus par cette partie:

 +(++v)+ 

Cela signifie simplement, dans le contexte, concaténer '<!--[if gt IE ' avec la valeur incrémentée de v et ensuite concaténer la chaîne nouvellement formée avec ']><i></i><![endif]-->' L'opérateur d'augmentation ++ agit pour renvoyer la valeur incrémentée de v , puisqu'il précède v . Si elle venait après v , la valeur actuelle de v serait renvoyée avant que l'augmentation ne se produise. Mozilla fait un meilleur travail d'explication que moi:

Cet opérateur augmente (ajoute un à) son opérande et renvoie une valeur. Si utilisé postfix, avec opérateur après opérande (par exemple, x ++), il renvoie la valeur avant d'incrémenter. Si le préfixe utilisé avec l'opérateur avant l'opérande (par exemple, ++ x), il renvoie la valeur après incrémentation.

Le premier commentaire conditionnel créé est toujours 4. La boucle continue jusqu'à div.getElementsByTagName('i')[0] que div.getElementsByTagName('i')[0] ne produit aucun élément DOM, évalue false et force la boucle à quitter.

Ce

 <div><!--[if gt IE 6]><i></i><![endif]--></div> 

Produit efficacement un DOM qui ressemble à

 <div><i></i></div> 

Dans les versions d'IE> 6. Mais dans les versions antérieures, et les navigateurs qui ne sont pas du tout IE, ils produisent

 <div></div> 

Donc, vous mettez dans cette version «si gt IE version » et selon que l'élément i fait partie du DOM, vous pouvez déterminer si vous êtes sur une version d'IE supérieure à v . Lorsque vous obtenez une valeur de v où l'élément i existe, vous avez terminé!