Comment ne!~ (not not tilde/bang bang tilde) modifier le résultat d'un appel de méthode 'contains/included'?

si vous lisez les commentaires au jQuery inArray page ici , il y a une déclaration intéressante:

!!~jQuery.inArray(elm, arr) 

maintenant, je crois qu'un double point d'exclamation convertira le résultat en boolean , avec la valeur de true . Ce que je ne comprends pas, c'est à quoi sert l'opérateur tilde ( ~ ) dans tout cela?

var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }

Refactoring if déclaration:

if (!!~jQuery.inArray("one", arr)) { alert("Found"); }

ventilation:

jQuery.inArray("one", arr)     // 0
~jQuery.inArray("one", arr)    // -1 (why?)
!~jQuery.inArray("one", arr)   // false
!!~jQuery.inArray("one", arr)  // true

j'ai aussi remarqué que si je place le tilde devant, le résultat est -2 .

~!!~jQuery.inArray("one", arr) // -2

Je ne comprends pas le but du tilde ici. Quelqu'un peut-il s'il vous plaît l'expliquer ou m'indiquer une ressource?

91
demandé sur Salman A 2012-02-16 22:08:09

13 réponses

l'opérateur tilde ne fait pas du tout partie de jQuery - il ne s'agit pas d'un opérateur en JavaScript.

Voir le Grand Mystère de La Tilde(~) .

vous recevez des nombres étranges dans vos expériences parce que vous effectuez une opération logique bitwise sur un entier (qui, pour autant que je sache, peut être stocké comme le complément de deux ou quelque chose comme ça...)

complément à Deux explique comment représenter un nombre en binaire. Je pense que j'avais raison.

54
répondu p.g.l.hall 2016-11-03 20:41:56

il y a une raison spéciale pour laquelle vous verrez parfois ~ appliqué devant $.inArray .

en gros,

~$.inArray("foo", bar)

est une façon plus courte de faire

$.inArray("foo", bar) !== -1

$.inArray renvoie l'index de l'élément dans le tableau si le premier argument est trouvé, et il retourne -1 si elle n'est pas trouvée. Cela signifie que si vous cherchez un booléen de "est cette valeur dans le tableau?"tu ne peux pas faire un booléen comparaison, depuis -1 est une valeur vraie, et quand $.inArray renvoie 0 (un falsy valeur), son réellement dans le premier élément du tableau.

L'application du ~ à l'opérateur bitwise fait que -1 devient 0 , et fait que 0 devient " -1. Ainsi, le fait de ne pas trouver la valeur dans le tableau et d'appliquer la valeur bitwise non se traduit par une valeur falsy (0), et toutes les autres valeurs retourneront des nombres non-0, et représenteront un résultat truthy.

if (~$.inArray("foo", ["foo",2,3])) {
    // Will run
}

et ça marchera comme prévu.

115
répondu Yahel 2014-10-01 00:11:19

!!~expr évalue à false quand expr est -1 autrement true .

Il est identique à expr != -1 , seulement cassé*


cela fonctionne parce que opérations JavaScript bitwise convertissez les opérandes en entiers signés 32 bits dans le format du complément de two. Ainsi !!~-1 est évalué comme suit:

   -1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two's complement representation of -1
  ~-1 = 0000 0000 0000 0000 0000 0000 0000 0000b // ~ is bitwise not (invert all bits)
   !0 = true                                     // ! is logical not (true for falsy)
!true = false                                    // duh

a valeur autre que -1 aura au moins un bit mis à zéro; l'Inverser créera une valeur truthy; l'application de ! opérateur deux fois à une valeur truthy renvoie booléen true.

utilisé avec .indexOf() et nous voulons seulement vérifier si le résultat est -1 ou non:

!!~"abc".indexOf("d") // indexOf() returns -1, the expression evaluates to false
!!~"abc".indexOf("a") // indexOf() returns  0, the expression evaluates to true
!!~"abc".indexOf("b") // indexOf() returns  1, the expression evaluates to true

* !!~8589934591 évalue à faux de sorte que ce abomination ne peut pas être utilisé de manière fiable pour tester -1 .

99
répondu Salman A 2018-01-05 19:11:46

~foo.indexOf(bar) est un raccourci courant pour représenter foo.contains(bar) parce que la fonction contains n'existe pas.

Typiquement la distribution à booléen est inutile en raison du concept de JavaScript des valeurs "falsy". Dans ce cas, il est utilisé pour forcer la sortie de la fonction true ou false .

32
répondu zzzzBov 2012-05-14 13:13:42

jQuery.inArray() renvoie -1 pour "non trouvé", dont le complément ( ~ ) est 0 . Ainsi, ~jQuery.inArray() renvoie une valeur falsy ( 0 ) pour "not found", et une valeur truthy (un entier négatif) pour "found". !! formalisera alors le falsy/truthy en véritable booléen false / true . Ainsi, !!~jQuery.inArray() donnera true pour "trouvé" et false pour "non trouvé".

18
répondu Amadan 2012-02-16 18:17:19

le ~ pour les 4 octets int est égal à cette formule -(N+1)

DONC

~0   = -(0+1)   // -1
~35  = -(35+1)  // -36 
~-35 = -(-35+1) //34 
11
répondu Mina Gabriel 2016-05-04 19:03:19

l'opérateur ~ est l'opérateur de complément en Bit. Le résultat entier de inArray() est soit -1, quand l'élément n'est pas trouvé, ou un entier non-négatif. Le complément bitwise de -1 (représenté en binaire comme tous les 1 bits) est zéro. Le complément bitwise de n'importe quel entier non-négatif est toujours non-zéro.

ainsi, !!~i sera true quand entier" i "est un entier non-négatif, et false quand" i " est exactement -1.

Note que ~ toujours contraint son opérande entier; c'est, c'forces non-entier valeurs à virgule flottante entier, ainsi que les valeurs non numériques.

10
répondu Pointy 2012-02-16 18:11:44

Tilde est bitwise pas - il inverse chaque bit de la valeur. Comme une règle générale, si vous utilisez ~ sur un numéro, son signe est inversé, puis 1 sera soustraite.

Ainsi, lorsque vous faites ~0 , vous obtenez -1 (0 inversé est -0, soustraire 1 est -1).

c'est essentiellement une façon élaborée, Super-micro-optimisée d'obtenir une valeur qui est toujours booléenne.

10
répondu Joe 2012-02-16 18:12:52

vous avez raison: ce code retournera false quand l'appel indexOf retournera -1; sinon true .

comme vous dites, il serait beaucoup plus raisonnable d'utiliser quelque chose comme

return this.modifiedPaths.indexOf(path) !== -1;
8
répondu LukeH 2012-05-14 11:34:58

l'opérateur ~ est l'opérateur en Bit. Cela signifie qu'il prend un nombre sous forme binaire et transforme tous les zéros en uns et les uns en zéros.

par exemple, le nombre 0 en binaire est 0000000 , tandis que -1 est 11111111 . De même, 1 est 00000001 en binaire, tandis que -2 est 11111110 .

6
répondu Frxstrem 2012-02-16 18:14:36

je pense que c'est là parce que c'est quelques caractères plus courts (ce que les auteurs de bibliothèque sont toujours après). Il utilise également des opérations qui ne prennent que quelques cycles machine lorsqu'ils sont compilés dans le code natif (par opposition à la comparaison à un nombre.)

je suis d'accord avec une autre réponse qu'il s'agit d'un surmenage mais peut-être pourrait avoir un sens dans une boucle serrée (nécessite l'estimation de gain de performance, cependant, sinon peut se révéler être une optimisation prématurée.)

3
répondu Alexander Pavlov 2012-05-14 11:25:54

je suppose que, puisqu'il s'agit d'une opération bitwise, c'est la manière la plus rapide (computationally cheap) de vérifier si path apparaît dans les chemins modifiés.

2
répondu panos2point0 2016-11-03 20:43:03

comme (~(-1)) === 0 , donc:

!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false
1
répondu Engineer 2012-05-14 11:37:20