3922 votes

Quel est le ! !! (not not) en JavaScript ?

J'ai vu un code qui semble utiliser un opérateur que je ne reconnais pas, sous la forme de deux points d'exclamation, comme ceci : !! . Quelqu'un peut-il me dire ce que fait cet opérateur ?

Le contexte dans lequel j'ai vu cela était le suivant,

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

1310 votes

Souviens-toi de "bang, bang tu es booléen".

117 votes

Pour mémoire, ne faites pas ce qui est cité. Faites ce qui suit if(vertical !== undefined) this.vertical = Boolean(vertical); - il est beaucoup plus propre et plus clair, ne nécessite aucune affectation inutile, est tout à fait standard, et est tout aussi rapide (sur les versions actuelles de FF et Chrome) jsperf.com/vitesse de conversion booléenne .

0 votes

"Tout programmeur digne de ce nom devrait savoir ce qui se passe..." - cela aide parfois le compilateur à générer un meilleur code dans les langages compilés. Je sais qu'il était recommandé par Microsoft lors de l'utilisation de code C, car il générait le meilleur code. (C'est probablement toujours le cas, mais je n'arrive pas à trouver la référence pour le moment).

3492voto

Stevo3000 Points 12725

Contraint oObject booléens. Si c'était falsey (par exemple, 0, null, undefined, etc.), il sera false, sinon, true.

!oObject  //Inverted boolean
!!oObject //Non inverted boolean so true boolean representation

Donc !! n'est pas un opérateur, c'est juste le ! opérateur de à deux reprises.

153 votes

Il convertit un non-booléen en un booléen inversé (par exemple, !5 serait faux, puisque 5 est une valeur non fausse en JS), puis l'inverse de manière à obtenir la valeur originale sous forme de booléen (donc !!5 serait vrai).

142 votes

Une façon simple de le décrire est la suivante : Boolean(5) === !!5 ; Même casting, moins de caractères.

55 votes

Elle est utilisée pour convertir les valeurs vraies en valeurs booléennes vraies et les valeurs fausses en valeurs booléennes fausses.

977voto

Tom Ritter Points 44352

C'est une façon horriblement obscure de faire une conversion de type.

! moyens NO . Ainsi !true est false y !false est true . !0 est true y !1 est false .

Il s'agit donc de convertir une valeur en booléen, de l'inverser, puis de l'inverser à nouveau.

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);

// Or just
val.enabled = Boolean(userId);

Nota: les deux dernières expressions ne sont pas exactement équivalentes à la première lorsqu'il s'agit de certains cas limites (lorsque userId est [] par exemple), en raison de la façon dont les != l'opérateur fonctionne et quelles sont les valeurs prises en compte sincère .

106 votes

!!false = false. !!true = true

130 votes

La variante "beaucoup plus facile à comprendre" est-elle vraiment beaucoup plus facile à comprendre ici ? La vérification contre 0 n'est pas une vérification réelle contre 0, mais une vérification contre la liste un peu bizarre des valeurs que Javascript considère comme égales à 0. userId ? true : false indique plus clairement qu'une conversion est en cours et gère le cas où la valeur de userId aurait été explicitement fixée à undefined

81 votes

Mon cerveau n'a aucun problème à décoder !!var en Boolean(var) et !! est plus rapide (moins d'instructions à traiter) et plus court que les autres solutions.

560voto

Salman A Points 60620

!!expr (deux ! suivi d'une expression) renvoie une valeur booléenne ( true o false ) en fonction de la vérité de l'expression. Elle a plus de sens lorsqu'elle est utilisée sur des types non booléens. Examinez les exemples suivants, en particulier le troisième exemple et les suivants :

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy
          !!(1/0) === true  // Infinity is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined value is falsy
      !!undefined === false // undefined primitive is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!

78 votes

À noter : !!new Boolean(false) // true

58 votes

...Mais aussi !!Boolean(false) // false

124 votes

new Boolean(false) est un objet et un objet est vrai même s'il contient une valeur erronée !

199voto

benny Points 453

Préparez du thé :

!! n'est pas un opérateur. C'est la double utilisation de ! -- qui est l'opérateur logique "non".


En théorie :

! détermine la "vérité" de ce qu'une valeur n'est pas :

  • La vérité est que false n'est pas true (c'est pourquoi !false résultats en true )

  • La vérité est que true n'est pas false (c'est pourquoi !true résultats en false )


!! détermine la "vérité" de ce qu'est une valeur pas pas :

  • La vérité est que true n'est pas pas true (c'est pourquoi !!true se traduit par true )

  • La vérité est que false n'est pas pas false (c'est pourquoi !!false se traduit par false )


Ce que nous souhaitons déterminer dans la comparaison, c'est la "vérité" à propos de la valeur d'une référence, et non la valeur de la référence elle-même. Il existe un cas d'utilisation où l'on peut vouloir connaître la vérité sur une valeur, même si l'on s'attend à ce que la valeur soit false (ou falsey), ou si l'on s'attend à ce que la valeur ne soit pas de typeof boolean .


En pratique :

Considérons une fonction concise qui détecte la fonctionnalité d'une caractéristique (et dans ce cas, la compatibilité avec la plate-forme) au moyen de la fonction dactylographie dynamique (alias "dactylographie du canard"). Nous voulons écrire une fonction qui renvoie true si le navigateur de l'utilisateur prend en charge la norme HTML5 <audio> mais nous ne voulons pas que la fonction génère une erreur si l'élément <audio> est indéfini ; et nous ne voulons pas utiliser try ... catch pour gérer les erreurs éventuelles (parce qu'elles sont grossières) ; et aussi nous ne voulons pas utiliser une vérification à l'intérieur de la fonction qui ne révélerait pas systématiquement la vérité sur la caractéristique (par exemple, document.createElement('audio') créera toujours un élément appelé <audio> même si HTML5 <audio> n'est pas pris en charge).


Voici les trois approches :

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

Chaque fonction accepte un argument pour un <tag> et un attribute à rechercher, mais ils renvoient chacun des valeurs différentes en fonction de ce que les comparaisons déterminent.

Mais ce n'est pas tout !

Certains d'entre vous ont probablement remarqué que dans cet exemple spécifique, on pourrait simplement vérifier la présence d'une propriété à l'aide de la fonction légèrement plus performant les moyens de vérifier si l'objet en question a une propriété. Il y a deux façons de procéder :

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

Nous nous éloignons du sujet...

Aussi rares que soient ces situations, il peut exister quelques scénarios dans lesquels le moyen le plus concis, le plus performant et, par conséquent, le plus préférable d'obtenir true à partir d'une valeur non booléenne, éventuellement indéfinie, se fait en utilisant la fonction !! . J'espère que cela sera ridiculement clair.

6 votes

Réponse tout à fait géniale, mais je ne vois pas l'utilité de la construction ! !!. Puisqu'un if() transforme déjà l'expression en booléen, transformer explicitement la valeur de retour d'une fonction de test en booléen est redondant - puisque la "véracité" === vrai dans la mesure où un if() La déclaration de l'UE va quand même dans ce sens. Ou bien ai-je oublié un scénario dans lequel vous avez BESOIN qu'une expression vraie soit réellement booléenne ? true ?

5 votes

@TomAuger if() permettent de remplacer les valeurs booléennes par des valeurs erronées, mais si vous souhaitez définir un drapeau booléen sur un objet, il ne le remplacera pas par une instruction if() le fait. Par exemple object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat() mettrait l'un ou l'autre true o false au lieu de la valeur de retour réelle. Un autre exemple est que tous les administrateurs sont id de 0 et les non-administrateurs sont id 1 ou plus. Pour obtenir true si quelqu'un n'est pas un administrateur, vous pouvez le faire person.isNotAdmin = !!admin.id . Peu de cas d'utilisation, mais c'est concis quand il y en a.

114voto

Crescent Fresh Points 54070

!! convertit la valeur située à sa droite en une valeur booléenne équivalente. (Pensez à la méthode du pauvre pour la "fonte de type".) Son intention est généralement de faire comprendre au lecteur que le code ne se préoccupe pas de ce qui se passe dans le pays. ce que la valeur de la variable, mais ce que sa "valeur "vérité es.

4 votes

Ou, dans le cas d'une valeur booléenne à droite, il ne fait rien.

3 votes

@Daniel : ! renverse toujours la valeur vers la droite. Dans le cas d'un booléen, la valeur la plus à droite du ! annule la valeur, tandis que l'élément le plus à gauche, le ! l'annule une fois de plus. L'effet net est qu'il n'y a pas de changement, mais la plupart des moteurs génèrent des codes op pour la double négation.

0 votes

Mais quel est l'intérêt ? Si je fais if(0){... Javascript sait déjà que c'est faux. Pourquoi est-il préférable de dire if(!!0){... ?

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