¿Qué es el operador JavaScript> y cómo lo utiliza?


Estaba buscando código de Mozilla que agrega un método de filtro a la matriz y tenía una línea de código que me confundió.

var len = this.length >>> 0;

Nunca he visto >>> usado en JavaScript antes.
¿Qué es y qué hace?

Author: Jon Seigel, 2009-11-30

6 answers

No solo convierte números no numéricos en Números, los convierte en Números que se pueden expresar como INT sin signo de 32 bits.

Aunque los números de JavaScript son flotadores de doble precisión (*), los operadores bitwise(<<, >>, &, | y ~) se definen en términos de operaciones en enteros de 32 bits. Haciendo una operación bitwise convierte el número a un 32-bit firmado int, perdiendo cualquier fracción y más alto-lugar bits que 32, antes de hacer el cálculo y luego convertir de nuevo numerar.

Así que hacer una operación bitwise sin efecto real, como un desplazamiento hacia la derecha de 0 bits >>0, es una forma rápida de redondear un número y asegurarse de que está en el rango int de 32 bits. Además, el operador triple >>>, después de hacer su operación sin signo, convierte los resultados de su cálculo a Número como un entero sin signo en lugar del entero con signo que hacen los demás, por lo que puede ser utilizado para convertir negativos a la versión de complemento de dos bits de 32 como un número grande. Usando >>>0 asegura que tienes un entero entre 0 y 0xFFFFFFFF.

En este caso esto es útil porque ECMAScript define los índices de matriz en términos de 32 bits int sin signo. Así que si estás tratando de implementar array.filter de una manera que duplique exactamente lo que dice el estándar ECMAScript Fifth Edition, lanzarías el número a 32-bit unsigned int de esta manera.

(En realidad hay poca necesidad práctica de esto, ya que esperamos que la gente no esté configurando array.length para 0.5, -1, 1e21 o 'LEMONS'. Pero estamos hablando de autores de JavaScript, así que nunca se sabe...)

Resumen:

1>>>0            === 1
-1>>>0           === 0xFFFFFFFF          -1>>0    === -1
1.7>>>0          === 1
0x100000002>>>0  === 2
1e21>>>0         === 0xDEA00000          1e21>>0  === -0x21600000
Infinity>>>0     === 0
NaN>>>0          === 0
null>>>0         === 0
'1'>>>0          === 1
'x'>>>0          === 0
Object>>>0       === 0

(*: bueno, se definen como comportarse como flotadores. No me sorprendería si algún motor JavaScript realmente utiliza ints cuando podría, por razones de rendimiento. Pero ese sería un detalle de implementación del que no se aprovecharía.)

 172
Author: bobince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-15 18:45:45

El operador de desplazamiento derecho sin signo se utiliza en todas las implementaciones del método array extra de Mozilla, para asegurar que la propiedad length es un entero de 32 bits sin signo.

La propiedad length de los objetos array es descrita en la especificación como:

Cada objeto Array tiene una propiedad length cuyo valor es siempre un entero no negativo menor que 232.

Este operador es el camino más corto para lograrlo, internamente los métodos de array utilizan el ToUint32 operación, pero ese método no es accesible y existe en la especificación para fines de implementación.

Las implementaciones de Mozilla array extras intentan ser compatibles con ECMAScript 5 , mira la descripción del método Array.prototype.indexOf (§15.4.4.14):

1. Let O be the result of calling ToObject passing the this value 
   as the argument.
2. Let lenValue be the result of calling the [[Get]] internal method of O with 
   the argument "length".
3. Let len be ToUint32(lenValue).
....

Como puede ver, solo quieren reproducir el comportamiento del método ToUint32 para cumplir con la especificación ES5 en una implementación ES3, y como dije antes, el unsigned right shift operator es la forma más fácil.

 54
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-21 04:34:47

Es el operador unsigned right bit shift. La diferencia entre esto y el operador de desplazamiento de bit derecho con signo , es que el operador de desplazamiento de bit derecho sin signo (>>>) rellena con ceros desde la izquierda, y el con signo operador de desplazamiento de bits derecho (>>) rellena con el bit de signo, preservando así el signo del valor numérico cuando se desplaza.

 28
Author: driis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-30 21:07:04

Driis ha explicado suficientemente qué es el operador y qué hace. Aquí está el significado detrás de él / por qué se usó:

Cambiando cualquier dirección por 0 does devuelve el número original y lanzará null a 0. Parece que el código de ejemplo que está viendo está usando this.length >>> 0 para asegurarse de que len sea numérico incluso si this.length no está definido.

Para muchas personas, las operaciones bitwise no están claras (y Douglas Crockford / jslint sugiere en contra de usar tales cosas). No significa que sea un error, pero existen métodos más favorables y familiares para hacer que el código sea más legible. Una forma más clara de asegurar que len es 0 es cualquiera de los dos métodos siguientes.

// Cast this.length to a number
var len = +this.length;

O

// Cast this.length to a number, or use 0 if this.length is
// NaN/undefined (evaluates to false)
var len = +this.length || 0; 
 27
Author: Justin Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:50

>>> es el unsigned operador de desplazamiento derecho (ver p. 76 de la especificación JavaScript 1.5), en contraposición al >>, el firmado operador de desplazamiento derecho.

>>> cambia los resultados de cambiar números negativos porque no conserva el bit de signo al cambiar. Las consecuencias de esto se pueden entender por ejemplo, de un interpretador:

$ 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

Así que lo que probablemente se pretende hacer aquí es obtener la longitud, o 0 si la longitud no está definida o no es un entero, según el ejemplo "cabbage" anterior. Creo que en este caso es seguro suponer que this.length nunca será < 0. Sin embargo, yo diría que este ejemplo es un truco desagradable, por dos razones:

  1. El comportamiento de <<< cuando se utilizan números negativos, un efecto secundario probablemente no se pretende (o es probable que ocurra) en el ejemplo anterior.

  2. La intención del código no es obvio, como lo verifica la existencia de esta pregunta.

La mejor práctica es probablemente usar algo más legible a menos que el rendimiento sea absolutamente crítico:

isNaN(parseInt(foo)) ? 0 : parseInt(foo)
 14
Author: fmark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-21 04:11:18

Dos razones:

  1. El resultado de >>> es una "integral"

  2. Undefined > > > 0 = 0 (ya que JS intentará coaccionar el LFS al contexto numérico, esto funcionará para " foo " > > > 0, etc. también)

Recuerde que los números en JS tienen una representación interna de double. Es solo una forma" rápida " de cordura de entrada básica para la longitud.

Sin embargo, -1 >>> 0 (oops, probablemente no una longitud deseada!)

 9
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-21 03:50:29