55 votes

Que fait de bien le décalage de bits avec zéro rempli par 0 ? (a >>> 0)

Je suis tombé sur ce morceau dans la documentation Javascript de Mozilla :

var len = this.length >>> 0;  

Je ne comprends pas vraiment pourquoi cela est fait. Quel est l'intérêt de décaler vers la droite en remplissant de zéros this.length par 0 ? Autant que je sache, cela ne fait strictement rien. Est-ce pour établir en toute sécurité une valeur par défaut pour len, même si this.length n'est pas un entier? Cela peut-il jamais être le cas de manière réalisable ? Si oui, quelle est la différence entre >> 0 et >>> 0 ?

57voto

CMS Points 315406

L'opérateur de décalage vers la droite non signé est utilisé dans toutes les implémentations de méthodes extras de tableau de Mozilla, pour garantir que la propriété length est un entier 32 bits non signé.

La propriété length des objets tableau est décrite dans la spécification comme suit :

Chaque objet tableau a une propriété de longueur dont la valeur est toujours un entier positif inférieur à 232.

Cet opérateur est le moyen le plus rapide d'y parvenir, les méthodes de tableau utilisent en interne l'opération ToUint32, mais cette méthode n'est pas accessible et n'existe pas dans la spécification à des fins d'implémentation.

Les implémentations des extras de tableau de Mozilla tentent d'être conformes à ECMAScript 5, consultez la description de la méthode Array.prototype.indexOf (§ 15.4.4.14) :

1\. Que O soit le résultat de l'appel de ToObject en passant la valeur this 
   comme argument.
2. Que lenValue soit le résultat de l'appel de la méthode interne \[\[Get\]\] de O avec 
   l'argument "length".
3. Que len soit **ToUint32(lenValue)**.
....

Comme vous pouvez le constater, ils veulent simplement reproduire le comportement de la méthode ToUint32 pour se conformer à la norme ES5 sur une implémentation ES3, et comme je l'ai dit auparavant, l'opérateur de décalage vers la droite non signé est la manière la plus simple.

15voto

fmark Points 15028

>>> est l'opérateur de décalage à droite non signé (voir p. 76 de la spécification JavaScript 1.5), contrairement au >>, l'opérateur de décalage à droite signé.

>>> modifie les résultats du décalage des nombres négatifs car il ne préserve pas le bit de signe lors du décalage. Les conséquences de ceci peuvent être comprises par exemple, à partir d'un interpretter :

$ 1 >> 0
1
$ 0 >> 0
0
$ -1 >> 0
-1
$ 1 >>> 0
1
$ 0 >>> 0
0
$ -1 >>> 0
4294967295
$(-1 >>> 0).toString(16)
"ffffffff"
$ "cabbage" >>> 0
0

Donc ce qui est probablement prévu ici est d'obtenir la longueur, ou 0 si la longueur est indéfinie ou n'est pas un entier, comme dans l'exemple "chou" ci-dessus. Je pense que dans ce cas, il est sûr de supposer que this.length ne sera jamais < 0. Néanmoins, je soutiendrais que cet exemple est une vilaine astuce, pour deux raisons :

  1. Le comportement de <<< lorsque l'on utilise des nombres négatifs, un effet secondaire probablement non voulu (ou probable de se produire) dans l'exemple ci-dessus.

  2. L'intention du code n'est pas évidente, comme le confirme l'existence de cette question.

La bonne pratique est probablement d'utiliser quelque chose de plus lisible sauf si la performance est absolument critique :

isNaN(parseInt(foo)) ? 0 : parseInt(foo)

10voto

Deux raisons :

  1. Le résultat de >>> est un "nombre entier"

  2. undefined >>> 0 = 0 (puisque JS va essayer de convertir le LFS en contexte numérique, cela fonctionnera également pour "foo" >>> 0, etc.)

N'oubliez pas que les nombres en JS ont une représentation interne en double. C'est juste un moyen "rapide" de sanity basique pour la longueur d'entrée.

Cependant, -1 >>> 0 (oups, probablement pas une longueur souhaitée !)

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