2012-10-12 70 views
29

me encontré con el siguiente código en un proyecto JS:¿Qué hace el operador | = en JavaScript?

var a = new Array(); 
a[0] = 0; 
for (var b = 0; b < 10; b++) { 
    a[0] |= b; 
} 

¿Qué significa el |= hacer en el cuerpo del bucle?

El ejemplo de código es dudoso, pero se ha presentado here por V8 para obtener un ejemplo de rendimiento mejorado.

Actualización Ejemplo

El ejemplo anterior es equivalente a var a = [15]; para la mayoría de los efectos. Un ejemplo más realista para el operador |= sería la creación de banderas binarias en una sola variable, por ejemplo en un objeto de permiso:

//Set up permission masks 
var PERMISSION_1_MASK = parseInt('0001',2); 
var PERMISSION_2_MASK = parseInt('0010',2); 
.. 

//Set up permissions 
userPermissions = 0; 
userPermissions |= hasPermissionOne && PERMISSION_1_MASK; 
userPermissions |= hasPermissionTwo && PERMISSION_2_MASK; 
.. 

//Use permissions 
if(userPermissions & PERMISSION_1_MASK){ 
    ..//Do stuff only allowed by permission 1 
} 
+0

Me acabo de dar cuenta de que el código es de aquí. http://www.html5rocks.com/en/tutorials/speed/v8/ – razpeitia

+2

@razpeitia lee la pregunta y encontrarás esa URL ... – ContentiousMaximus

Respuesta

70
a[0] |= b 

es básicamente

a[0] = a[0] | b 

"|" es un or bitwise operator (por cierto:.. Los documentos MDN están muy bien escritos y realmente claro si el PO es querer escribir y entender JS, a continuación, la documentación MDN son un gran recurso)

actualización Cuando a[0] se asigna 0, a[0] en binario es 0000.En el bucle,

  1. b = 0

    a[0] = 0 (base 10) = 0000 (base 2) 
    b = 0 (base 10) = 0000 (base 2) 
            --------------- 
    a[0] | b   = 0000 (base 2) = 0 (base 10) 
    
  2. b = 1

    a[0] = 0 (base 10) = 0000 (base 2) 
    b = 1 (base 10) = 0001 (base 2) 
            --------------- 
    a[0] | b   = 0001 (base 2) = 1 (base 10) 
    
  3. b = 2

    a[0] = 1 (base 10) = 0001 (base 2) 
    b = 2 (base 10) = 0010 (base 2) 
            --------------- 
    a[0] | b   = 0011 (base 2) = 3 (base 10) 
    
  4. b = 3

    a[0] = 3 (base 10) = 0011 (base 2) 
    b = 3 (base 10) = 0011 (base 2) 
            --------------- 
    a[0] | b   = 0011 (base 2) = 3 (base 10) 
    
  5. b = 4

    a[0] = 3 (base 10) = 0011 (base 2) 
    b = 4 (base 10) = 0100 (base 2) 
            --------------- 
    a[0] | b   = 0111 (base 2) = 7 (base 10) 
    
  6. b = 5

    a[0] = 7 (base 10) = 0111 (base 2) 
    b = 5 (base 10) = 0101 (base 2) 
            --------------- 
    a[0] | b   = 0111 (base 2) = 7 (base 10) 
    
  7. b = 6

    a[0] = 7 (base 10) = 0111 (base 2) 
    b = 6 (base 10) = 0110 (base 2) 
            --------------- 
    a[0] | b   = 0111 (base 2) = 7 (base 10) 
    
  8. b = 7

    a[0] = 7 (base 10) = 0111 (base 2) 
    b = 7 (base 10) = 0111 (base 2) 
            --------------- 
    a[0] | b   = 0111 (base 2) = 7 (base 10) 
    
  9. b = 8

    a[0] = 7 (base 10) = 0111 (base 2) 
    b = 8 (base 10) = 1000 (base 2) 
            --------------- 
    a[0] | b   = 1111 (base 2) = 15 (base 10) 
    
  10. b = 9

    a[0] = 15 (base 10) = 1111 (base 2) 
    b = 9 (base 10) = 1001 (base 2) 
            --------------- 
    a[0] | b   = 1111 (base 2) = 15 (base 10) 
    

Al final del bucle el valor de a[0] es 15

+22

+1 para recorrer el ciclo – WildlyInaccurate

+0

@kidmenot: Impresionante, gracias. – ContentiousMaximus

+0

@ user1638092 contento de ser de ayuda :) –

46
x |= y; 

es equivalente a

x = x | y; 

donde | gradas para en bits O.

+0

¿Hay un significado idiomático? O algún truco, como cuando en el suelo flota con '~~'? – katspaugh

+1

@katspaugh Hay.Por ejemplo, se puede usar para una codificación eficiente y la comprobación de privilegios (esto también se ajustaría al código OP). Lea [este artículo] (http://www.php4every1.com/tutorials/create-permissions-using-bitwise-operators-in-php/). – freakish

+1

@katspaugh ¿Qué quisiste decir con "piso abajo flota con ~~"? ¡Nunca he oído hablar de tal cosa! –

7

Al igual que con la mayoría de los operadores de asignación, que es equivalente a aplicar el operador utilizando el valor izquierda de nuevo:

a |= b 
a = a | b 

al igual que

a += b 
a = a + b 

Look en Moz Dev Net por más.

[Editar: Brain fail, mixed up | y ||. Necesito más café. Modificado a continuación]

Desde | es el operador binario OR, el resultado de a|b será el número entero que representa la cadena de bits con todos los bits 1 de a y b. Tenga en cuenta que javascript no tiene tipos nativos int o bitstring, por lo que primero emitirá a y b en int, luego realizará un OR bit a bit en los bits. Entonces 9 | 2 en binario es 1001 | 0010 = 1011, que es 11, pero 8 | 2 = 8.

El efecto es agregar los bits de indicador de b en a. Así que si usted tiene alguna bandera WEEVILFLAG=parseInt(00001000,2):

// a = parseInt(01100001,2) 
if(isWeevilish(a)) 
    a |= WEEVILFLAG; 
// now a = parseInt(01101001,2) 

establecerá que el bit a 1 en una.

+1

¿Entonces esto es lo mismo que el lógico o? P.ej. var a = "título" || x – ContentiousMaximus

+3

Está confundiendo O OR y bitwise OR. – katspaugh

+1

Bah. Bitwise OR no lógico OR. Los cerebros son cosas divertidas. Corregido ahora. –

11

Funciona tipo de de esta manera: si b es mayor que a, b se agrega a a.

Lo que ocurre en realidad es a = a | b, al igual que para otros operadores. Esto significa a = a BITWISE OR b que se explica here.

Por ejemplo, este es el resultado de unas pocas operaciones:

var a = 1; 
a |= 2; // a = 3 
a |= 2; // a = 3 
a |= 4; // a = 7 

Espero que ayude.

+0

no estoy seguro: b: 0 a [0]: 0 b: 1 a [0]: 1 b: 2 a [0]: 3 b: 3 a [0]: 3 b: 4 a [0]: 7 b: 5 a [0]: 7 b: 6 a [0]: 7 b: 7 a [0]: 7 b: 8 a [0]: 15 b: 9 a [0]: 15 – ContentiousMaximus

+0

Esto debería ser una explicación correcta, aunque algunos otros lo han explicado más a fondo. –

5

Devuelve uno en cada posición de bit para la cual los bits correspondientes de uno o ambos operandos son uno.

Código: resultado = a | segundo;

^ es el operador XOR bit a bit, que devuelve uno para cada posición donde uno (no los dos) de los bits correspondientes de sus operandos es uno. El siguiente ejemplo devuelve 4 (0100):