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?
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.
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.
!!~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
.
~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
.
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é".
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
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.
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.
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;
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
.
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.)
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.
comme (~(-1)) === 0
, donc:
!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false