web-dev-qa-db-fra.com

Que fait un tilde quand il précède une expression?

var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
           ? 'value'
           : 'innerHTML'

Je l'ai vu dans une réponse et je ne l'avais jamais vue auparavant.

Qu'est-ce que ça veut dire?

175
wwaawaw

~ Est un opérateur au niveau du bit qui retourne tous les bits de son opérande.

Par exemple, si votre numéro était 1, Sa représentation binaire de IEEE 754 float (comment JavaScript traite les nombres) serait ...

0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

Donc ~ Convertit son opérande en un entier de 32 bits (les opérateurs de bits en JavaScript le font) ...

0000 0000 0000 0000 0000 0000 0000 0001

S'il s'agissait d'un nombre négatif, il serait stocké dans le complément à 2: inverser tous les bits et ajouter 1.

... et retourne ensuite tous ses bits ...

1111 1111 1111 1111 1111 1111 1111 1110

Alors, à quoi sert-il alors? Quand peut-on jamais l'utiliser?

Il a de nombreuses utilisations. Si vous écrivez des choses de bas niveau, c'est pratique. Si vous profilez votre application et trouvez un goulot d'étranglement, vous pourrez la rendre plus performante en utilisant des astuces au niveau des bits (comme un outil possible dans un sac beaucoup plus grand).

C’est aussi une astuce peu claire - pour transformer la fonction indexOf() trouvée renvoie la valeur dans vérité (en faisant non trouvé comme falsy ) et l’utilise souvent pour son effet secondaire, qui consiste à tronquer les nombres en 32 bits (et à laisser tomber sa décimale en la doublant, ce qui revient au même que Math.floor() pour les nombres positifs).

Je dis pas clair car ce n’est pas immédiatement évident à quoi il sert. Généralement, vous voulez que votre code communique clairement avec les autres personnes qui le lisent. Bien que l'utilisation de ~ Puisse paraître cool , elle est généralement trop intelligente pour son propre bien. :)

C'est également moins pertinent maintenant que JavaScript a Array.prototype.includes() et String.prototype.includes() . Ceux-ci renvoient une valeur booléenne. Si votre ou vos plates-formes cibles le prennent en charge, préférez-le pour tester l'existence d'une valeur dans une chaîne ou un tableau.

248
alex

En l'utilisant avant une expression indexOf(), vous obtiendrez un résultat vrai/faux au lieu de l'index numérique qui est directement renvoyé.

Si la valeur de retour est -1, Alors ~-1 Est 0 Car -1 Est une chaîne de tous les 1 bits. Toute valeur supérieure ou égale à zéro donnera un résultat différent de zéro. Ainsi,

if (~someString.indexOf(something)) {
}

provoquera l'exécution du code if lorsque "quelque chose" est dans "une corde". Si vous essayez d'utiliser .indexOf() comme un booléen directement, cela ne fonctionnera pas, car il renvoie parfois zéro (lorsque "quelque chose" est au début de la chaîne).

Bien sûr, cela fonctionne aussi:

if (someString.indexOf(something) >= 0) {
}

et c'est considérablement moins mystérieux.

Parfois, vous verrez aussi ceci:

var i = ~~something;

L'utilisation de l'opérateur ~ À deux reprises est un moyen rapide de convertir une chaîne en un entier 32 bits. Le premier ~ Effectue la conversion et le second ~ Renvoie les bits. Bien sûr, si l'opérateur est appliqué à quelque chose qui ne peut pas être converti en un nombre, vous obtenez NaN. (edit - en fait c'est le deuxième ~ qui est appliqué en premier, mais vous voyez l'idée.)

98
Pointy

Le ~ Est Opérateur binaire PAS , ~x Est à peu près identique à -(x+1). C'est plus facile à comprendre, en quelque sorte. Alors:

~2;    // -(2+1) ==> -3

Considérons -(x+1). -1 Peut effectuer cette opération pour produire un 0.

En d'autres termes, ~ Utilisé avec une plage de valeurs numériques produira une valeur falsy (contrainte à false à partir de 0) Uniquement pour la valeur d'entrée -1 sinon, toute autre valeur de vérité.

Comme nous le savons, -1 Est communément appelée valeur sentinelle . Il est utilisé pour de nombreuses fonctions qui renvoient des valeurs >= 0 Pour success et -1 Pour échec en langage C. Quelle est la même règle de retour valeur de indexOf() en JavaScript.

Il est courant de vérifier la présence ou l'absence d'une sous-chaîne dans une autre chaîne

var a = "Hello Baby";

if (a.indexOf("Ba") >= 0) {
    // found it
}
if (a.indexOf("Ba") != -1) { 
    // found it
}

if (a.indexOf("aB") < 0) { 
    // not found
}
if (a.indexOf( "aB" ) == -1) { 
    // not found
}

Cependant, il serait plus facile de le faire avec ~ Comme ci-dessous

var a = "Hello Baby";

~a.indexOf("Ba");         // -7   -> truthy
if (~a.indexOf("Ba")) {   // true
    // found it
}

~a.indexOf("aB");         // 0    -> falsy
!~a.indexOf("aB");        // true
if (!~a.indexOf( "aB" )) {  // true
    // not found
}

Vous ne connaissez pas JS: Types & Grammar de Kyle Simpson

23
zangw

~indexOf(item) arrive assez souvent, et les réponses ici sont excellentes, mais peut-être que certaines personnes ont juste besoin de savoir comment les utiliser et "ignorer" la théorie:

   if (~list.indexOf(item)) {
     // item in list
   } else {
     // item *not* in list
   }
20
Jorge Bucaran

Pour ceux qui envisagent d'utiliser l'astuce tilde pour créer une valeur vérité à partir d'un résultat indexOf, elle est plus explicite et moins magique à la place utilisez la méthode includes sur String .

'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false

Notez qu'il s'agit d'une nouvelle méthode standard à partir d'ES 2015 et qu'elle ne fonctionnera donc pas avec les anciens navigateurs. Dans les cas où cela est important, envisagez d'utiliser String.prototype.includes polyfill .

Cette fonctionnalité est également disponible pour les tableaux utilisant la même syntaxe :

['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false

Voici le Array.prototype.includes polyfill si vous avez besoin de la prise en charge de navigateurs plus anciens.

11
Dana Woodman