2011-04-21 16 views
15

la siguiente función está diseñada para implementar la propiedad indexOf en IE. Si alguna vez has tenido que hacer esto, estoy seguro de que ya lo has visto antes.Operador de JavaScript extraño: expr >>> 0

if (!Array.prototype.indexOf){ 

    Array.prototype.indexOf = function(elt, from){ 

    var len = this.length >>> 0; 
    var from = Number(arguments[1]) || 0; 

    from = (from < 0) 
     ? Math.ceil(from) 
     : Math.floor(from); 

    if (from < 0) 
     from += len; 

    for (; from < len; from++){ 
     if (from in this &&  
      this[from] === elt) 
     return from; 
    } 

    return -1;  
    }; 
} 

Me pregunto si es común el uso de tres mayor que las señales ya que el autor ha hecho en el cheque longitud inicial?

var len = this.length >>> 0

Hacer esto en una consola simplemente devuelve la longitud del objeto que pase a ella, no verdadera o falsa, lo que me dejó pensando en la finalidad de la sintaxis. ¿Es esta alguna técnica Ninja de alto nivel de JavaScript que no conozco? Si es así, ¡por favor ilumíname!

Respuesta

18

Fuente: LINK

Este es el relleno de cero desplazamiento a la derecha operador que desplaza el binario representación del primer operando a la derecha por el número de lugares especificados por el segundo operando. Los bits desplazados a la derecha se descartan y se agregan ceros a la izquierda. Con un número positivo que se obtendría el mismo resultado que con los números de propagación de signo operador de desplazamiento a la derecha, pero negativas pierden su signo convertirse en positivo como en el siguiente ejemplo, que (suponiendo 'a' para ser - 13) devolvería 1073741820:

Código:

result = a >>> b; 
+0

Guau, me quedé mudo:) Gracias, señor, me han iluminado, le da el toque. – Hacknightly

+0

Dos segundos demasiado lento. Grats! –

+2

Entonces, ¿cuál es exactamente el efecto del uso en el ejemplo 'var len = this.length >>> 0'? Eso parece no hacer nada. –

8

El >>> (desplazamiento a la derecha) operador binario es simplemente cambiar el derecho más bits de un número de un número especificado de veces, y el relleno con ceros por la izquierda.

Nota: En los ejemplos siguientes, el número entre llaves después de un número indica en qué base está. 2 es para binario, 10 para decimal.

Por ejemplo, 4 >>> 1 haría:

4(10) = 100(2) 

4(10) >>> 1(10) = 010(2) = 2(10) 
     shift once to the right 

Otros ejemplos:

4(10) >>> 2(10) = 100(2) >>> 2(10) = 001(2) = 1(10) 

10(10) >>> 4(10) = 1010(2) >>> 4(10) = 0000(2) = 0(10) 

15(10) >>> 1(10) = 1111(2) >>> 1(10) = 0111(2) = 7 

La forma en que recuerdo es para mover la cantidad necesaria de bits a la derecha, y luego escribir el número . Al igual que, en el último ejemplo, simplemente moví todo a la derecha una vez, por lo que el resultado es 0111.

Cambiando 0 veces no ... nada. No tengo idea de por qué está ahí.

+0

Muy buena respuesta señor! +1 – Hacknightly

8

>>> es el operador Zero-fill right shift.Como ya se estableció:

Este operador desplaza el primer operando al número especificado de bits a a la derecha. Los bits en exceso desplazados a la derecha se descartan. Zero bits se desplazan desde la izquierda. El bit de signo se convierte en 0, por lo que el resultado siempre es positivo.

También se menciona here que:

operadores bit a bit tratan a sus operandos como una secuencia de 32 bits (ceros y unos) , más que como decimal, hexadecimal, o números octales. [...] Los operadores de Bitwise realizan sus operaciones en dichas representaciones binarias , pero devuelven valores numéricos de JavaScript estándar.

Juntos, estos estados afirmar que expr >>> 0 siempre devolverá un número positivo como sigue:

  1. expr es echado en un entero de 32 bits para operación en modo bit
  2. >>> 0 no tiene ningún efecto (no hay bits de se desplazan)
  3. El resultado se convierte en un Number

Estas son algunas expresiones y sus resultados:

 1 >>> 0 // 1 -- Number cast to 32-bit integer then back to Number 
     "1" >>> 0 // 1 -- String cast to 32-bit integer then back to Number 
undefined >>> 0 // 0 -- failed cast yields zero 

Otros casos interesantes:

 1.1 >>> 0 // 1   -- decimal portion gets it 
     -1 >>> 0 // 4294967295 -- -1 = 0xFFFFFFFF 
       //    Number(0xFFFFFFFF) = 4294967295 
     "A" >>> 0 // 0   -- cast failed 
    "1e2" >>> 0 // 100  -- 1x10^2 is 100 
    "1e10" >>> 0 // 1410065408 -- 1x10^10 is 10000000000 
       //    10000000000 is 0x00000002540BE400 
       //    32 bits of that number is 0x540BE400 
       //    Number(0x540BE400) is 1410065408 

Nota: se dará cuenta de que ninguno de ellos regresan NaN.

Cuestiones relacionadas