Explicación del operador

operador

Preguntas reales clásicas

  • En el siguiente código, ¿ bajo qué circunstancias a ejecutará la declaración de salida e imprimirá 1 ?
var a = ?;
if(a == 1 && a == 2 && a == 3){
    
    
 	console.log(1);
}

1. Operadores aritméticos

JavaScript proporciona un total de 10 operadores aritméticos para completar operaciones aritméticas básicas.

  • Operador de suma :x + y
  • Operador de resta :x - y
  • Operador de multiplicación :x * y
  • Operador de división :x / y
  • Operador exponencial :x ** y
  • Operador restante :x % y
  • Operador de incremento : ++xox++
  • Operador de decremento : --xox--
  • Operadores numéricos :+x
  • Operadores numéricos negativos :-x

Las operaciones de resta, multiplicación y división son relativamente sencillas, simplemente realizan las operaciones matemáticas correspondientes.

A continuación se presentan varios otros operadores aritméticos, centrándose en el operador de suma.

operador de suma

(1) Reglas básicas

El operador de suma ( +) es el operador más común y se utiliza para encontrar la suma de dos números.

1 + 1 // 2

JavaScript permite la suma no numérica.

true + true // 2
1 + true // 2

En el código anterior, la primera línea es la suma de dos valores booleanos y la segunda línea es la suma de un valor numérico y un valor booleano. En ambos casos, los valores booleanos se convierten automáticamente a valores numéricos y luego se suman.

Lo que es especial es que si se agregan dos cadenas, el operador de suma se convertirá en el operador de conexión, devolviendo una nueva cadena y concatenando las dos cadenas originales.

'a' + 'bc' // "abc"

Si un operador es una cadena y el otro operador no es una cadena, la no cadena se convertirá en una cadena y luego se concatenará.

1 + 'a' // "1a"
false + 'a' // "falsea"

El operador de suma decide en tiempo de ejecución si realiza la suma o la conexión. En otras palabras, diferentes operadores dan lugar a diferentes comportamientos gramaticales, fenómeno que se denomina "sobrecarga". Dado que el operador de suma está sobrecargado, puede realizar dos operaciones, por lo que debe tener cuidado al usarlo.

'3' + 4 + 5 // "345"
3 + 4 + '5' // "75"

En el código anterior, debido al orden de las operaciones de izquierda a derecha, diferentes posiciones de la cadena conducirán a resultados diferentes.

A excepción del operador de suma, otros operadores aritméticos (como resta, división y multiplicación) no están sobrecargados. Sus reglas son: todos los operadores se convierten en valores numéricos y luego se realizan las operaciones matemáticas correspondientes.

1 - '2' // -1
1 * '2' // 2
1 / '2' // 0.5

En el código anterior, los operadores de resta, división y multiplicación convierten automáticamente cadenas en valores numéricos y luego realizan operaciones.

(2) Adición de objetos

Si el operador es un objeto, se debe convertir a un valor de tipo primitivo antes de agregarlo.

var obj = {
    
     p: 1 };
obj + 2 // "[object Object]2"

En el código anterior, objel valor del objeto convertido al tipo original es [object Object]y, cuando se agrega, 2se obtiene el resultado anterior.

El objeto se convierte en un valor de tipo primitivo según las siguientes reglas.

Primero, los métodos del objeto valueOfse llaman automáticamente.

var obj = {
    
     p: 1 };
obj.valueOf() // { p: 1 }

En términos generales, el valueOfmétodo del objeto siempre devuelve el objeto en sí, en este momento el método del objeto se llama automáticamente toStringy se convierte en una cadena.

var obj = {
    
     p: 1 };
obj.valueOf().toString() // "[object Object]"

Los métodos del objeto toStringregresan por defecto [object Object], por lo que se obtiene el resultado del ejemplo anterior.

Después de conocer esta regla, podrás definir tus propios valueOfmétodos o toStringmétodos para obtener los resultados deseados.

var obj = {
    
    
  valueOf: function () {
    
    
    return 1;
  }
};

obj + 2 // 3

En el código anterior, definimos el método objdel objeto a devolver , así que lo obtuvimos . En este ejemplo, dado que el método devuelve directamente un valor de tipo primitivo, ya no se llama al método.valueOf1obj + 23valueOftoString

A continuación se muestra un ejemplo de un toStringmétodo personalizado.

var obj = {
    
    
  toString: function () {
    
    
    return 'hello';
  }
};

obj + 2 // "hello2"

En el código anterior, el método objdel objeto toStringdevuelve una cadena hello. Como se mencionó anteriormente, siempre que uno de los operadores sea una cadena, el operador de suma se convierte en un operador de concatenación y devuelve la cadena concatenada.

Aquí hay un caso especial: si el operador es una Dateinstancia de un objeto, toStringel método se ejecutará primero.

var obj = new Date();
obj.valueOf = function () {
    
     return 1 };
obj.toString = function () {
    
     return 'hello' };

obj + 2 // "hello2"

En el código anterior, el objeto objes una instancia de un objeto, los métodos y métodos Dateestán personalizados y el método resultante se ejecuta primero.valueOftoStringtoString

operador restante

El operador restante ( %) devuelve el resto obtenido al dividir el operador anterior por el siguiente operador.

12 % 5 // 2

Tenga en cuenta que el signo del resultado de una operación está determinado por el signo del primer operador.

-1 % 2 // -1
1 % -2 // 1

Entonces, para obtener el valor restante correcto para un número negativo, primero puedes usar la función de valor absoluto.

// 错误的写法
function isOdd(n) {
    
    
  return n % 2 === 1;
}
isOdd(-5) // false
isOdd(-4) // false

// 正确的写法
function isOdd(n) {
    
    
  return Math.abs(n % 2) === 1;
}
isOdd(-5) // true
isOdd(-4) // false

El operador restante también se puede utilizar para operar con números de coma flotante. Sin embargo, dado que los números de punto flotante no son valores exactos, no se pueden obtener resultados completamente precisos.

6.5 % 2.1
// 0.19999999999999973

Operadores de incremento y decremento

Los operadores de incremento y decremento son operadores unarios y requieren un solo operador. Su función es convertir primero el operador en un valor numérico y luego sumar 1 o restar 1. Modifican la variable original.

var x = 1;
++x // 2
x // 2

--x // 1
x // 1

La variable en el código anterior xaumenta y luego regresa 2, y luego disminuye y regresa 1. Ambos casos harán que xel valor de la variable original cambie.

Después de la operación, el valor de la variable cambia, este efecto se denomina efecto secundario de la operación. Los operadores de incremento y decremento son los únicos dos operadores que tienen efectos secundarios. Los otros operadores no cambian el valor de la variable.

Una cosa a tener en cuenta acerca de los operadores de incremento y decremento automático es que cuando se colocan después de una variable, el valor antes de la operación de la variable se devolverá primero y luego se realizará la operación de incremento/decremento automático; cuando se colocan antes de la variable, primero se realizará la operación de incremento/decremento automático, la operación de resta y luego devolverá el valor de la operación de la variable.

var x = 1;
var y = 1;

x++ // 1
++y // 2

En el código anterior, xel valor actual se devuelve primero y luego se incrementa, por lo que obtenemos 1; yprimero se incrementa y luego se devuelve el nuevo valor, por lo que obtenemos 2.

Operador Numérico, Operador Numérico Negativo

El operador numérico ( +) también usa el signo más, pero es un operador unario (requiere solo un operando), mientras que el operador de suma es un operador binario (requiere dos operandos).

Los operadores numéricos se utilizan para convertir cualquier valor en un valor numérico ( Numberlo mismo que las funciones).

+true // 1
+[] // 0
+{
    
    } // NaN

El código anterior indica que después de que el valor no numérico pasa a través del operador numérico, se convierte en un valor numérico (la última línea NaNtambién es un valor numérico). Para conocer reglas de conversión de tipos específicas, consulte el capítulo "Conversión de tipos de datos".

El operador numérico negativo ( -) también tiene la función de convertir un valor en un valor numérico, pero el valor obtenido es positivo y negativo. Usar dos operadores numéricos negativos juntos es equivalente a operadores numéricos.

var x = 1;
-x // -1
-(-x) // 1

Los paréntesis en la última línea del código anterior son indispensables; de lo contrario, se convertirá en un operador de autodecremento.

Tanto el operador numérico como el operador numérico negativo devuelven un nuevo valor sin cambiar el valor de la variable original.

operador exponente

El operador exponente ( **) completa la operación exponente, el primer operador es la base y el último operador es el exponente.

2 ** 4 // 16

Tenga en cuenta que el operador exponencial es asociativo por la derecha, no asociativo por la izquierda. Es decir, cuando se utilizan varios operadores exponenciales juntos, el que está más a la derecha se calcula primero.

// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2
// 512

En el código anterior, dado que el operador exponencial es asociativo derecho, primero se calcula el segundo operador exponencial, no el primero.

operador de asignación

Los operadores de asignación se utilizan para asignar valores a variables.

El operador de asignación más común, por supuesto, es el signo igual ( =).

// 将 1 赋值给变量 x
var x = 1;

// 将变量 y 的值赋值给变量 x
var x = y;

El operador de asignación también se puede combinar con otros operadores para formar variaciones. A continuación se muestra la combinación con operadores aritméticos.

// 等同于 x = x + y
x += y

// 等同于 x = x - y
x -= y

// 等同于 x = x * y
x *= y

// 等同于 x = x / y
x /= y

// 等同于 x = x % y
x %= y

// 等同于 x = x ** y
x **= y

La siguiente es la combinación con operadores de bits (para operadores de bits, consulte la introducción más adelante).

// 等同于 x = x >> y
x >>= y

// 等同于 x = x << y
x <<= y

// 等同于 x = x >>> y
x >>>= y

// 等同于 x = x & y
x &= y

// 等同于 x = x | y
x |= y

// 等同于 x = x ^ y
x ^= y

Estos operadores de asignación compuesta primero realizan la operación especificada y luego devuelven el valor resultante a la variable de la izquierda.

2. Operadores de comparación

Los operadores de comparación se utilizan para comparar el tamaño de dos valores y luego devolver un valor booleano que indica si se cumple la condición especificada.

2 > 1 // true

El código anterior compara 2si es mayor que o no 1y devuelve true.

Tenga en cuenta que los operadores de comparación pueden comparar valores de todo tipo, no solo valores numéricos.

JavaScript proporciona un total de 8 operadores de comparación.

  • >mayor que el operador
  • <menos que operador
  • <=menor o igual que el operador
  • >=Operador mayor o igual que
  • ==operador de igualdad
  • ===operador de igualdad estricta
  • !=operador de desigualdad
  • !==operador de desigualdad estricta

Estos ocho operadores de comparación se dividen en dos categorías: comparación de igualdad y comparación de no igualdad. Las reglas de los dos son diferentes. Para comparaciones no iguales, el algoritmo primero verifica si los dos operadores son cadenas. Si es así, compárelos en el orden del diccionario (en realidad comparando puntos de código Unicode); de lo contrario, convierta ambos operadores en valores numéricos. y luego compare los valores numéricos.

Operador de no igualdad: comparación de cadenas

Las cadenas se comparan en orden lexicográfico.

'cat' > 'dog' // false
'cat' > 'catalog' // false

El motor JavaScript compara internamente primero el punto de código Unicode del primer carácter. Si son iguales, compare el punto del código Unicode del segundo carácter, y así sucesivamente.

'cat' > 'Cat' // true'

En el código anterior, el cpunto de código Unicode en minúscula ( 99) es mayor que el Cpunto de código Unicode en mayúscula ( 67), por lo que se devuelve true.

Dado que todos los caracteres tienen puntos de código Unicode, también se pueden comparar los caracteres chinos.

'大' > '小' // false

En el código anterior, el punto de código Unicode "grande" es 22823 y el "pequeño" es 23567, por lo que se devuelve false.

Operador de no igualdad: comparación de no cadenas

Si al menos uno de los dos operadores no es una cadena, es necesario dividirlo en las dos situaciones siguientes.

(1) Valor de tipo primitivo

Si ambos operadores son valores de tipo primitivo, primero se convierten a valores numéricos y luego se comparan.

5 > '4' // true
// 等同于 5 > Number('4')
// 即 5 > 4

true > false // true
// 等同于 Number(true) > Number(false)
// 即 1 > 0

2 > true // true
// 等同于 2 > Number(true)
// 即 2 > 1

En el código anterior, las cadenas y los valores booleanos se convertirán primero en valores numéricos y luego se compararán.

Aquí debes prestar atención a NaNla comparación con. Se devuelve cualquier valor (incluido NaNél mismo) que NaNse compara utilizando el operador de no igualdad false.

1 > NaN // false
1 <= NaN // false
'1' > NaN // false
'1' <= NaN // false
NaN > NaN // false
NaN <= NaN // false

(2) objeto

Si el operador es un objeto, se convertirá en un valor de tipo primitivo y luego se comparará.

Para convertir un objeto en un valor de un tipo primitivo, el algoritmo consiste en llamar primero valueOfal método; si el objeto devuelto sigue siendo un objeto, entonces llamar al toStringmétodo. Para obtener una explicación detallada, consulte el capítulo "Conversión de tipos de datos".

var x = [2];
x > '11' // true
// 等同于 [2].valueOf().toString() > '11'
// 即 '2' > '11'

x.valueOf = function () {
    
     return '1' };
x > '11' // false
// 等同于 [2].valueOf() > '11'
// 即 '1' > '11'

Lo mismo ocurre con las comparaciones entre dos objetos.

[2] > [1] // true
// 等同于 [2].valueOf().toString() > [1].valueOf().toString()
// 即 '2' > '1'

[2] > [11] // true
// 等同于 [2].valueOf().toString() > [11].valueOf().toString()
// 即 '2' > '11'

{
    
     x: 2 } >= {
    
     x: 1 } // true
// 等同于 { x: 2 }.valueOf().toString() >= { x: 1 }.valueOf().toString()
// 即 '[object Object]' >= '[object Object]'

operador de igualdad estricta

JavaScript proporciona dos operadores de igualdad: ==y ===.

En pocas palabras, la diferencia entre ellos es que el operador de igualdad ( ==) compara si dos valores son iguales, y el operador de igualdad estricta ( ===) compara si son "el mismo valor". Si los dos valores no son del mismo tipo, el operador de igualdad estricta ( ===) los devuelve directamente false, mientras que el operador de igualdad ( ==) los convierte al mismo tipo y luego usa el operador de igualdad estricta para comparar.

(1) Diferentes tipos de valores

Si los dos valores son de diferentes tipos, devuélvalos directamente false.

1 === "1" // false
true === "true" // false

El código anterior compara el valor numérico 1con la cadena "1" y el valor booleano truecon la cadena "true". Debido a que los tipos son diferentes, los resultados son los mismos false.

(2) Valores de tipo primitivo de la misma clase.

Al comparar valores de tipo primitivo (valores numéricos, cadenas, valores booleanos) del mismo tipo, si los valores son iguales, se devuelven true, si los valores son diferentes, se devuelven false.

1 === 0x1 // true

El código anterior compara decimal 1y hexadecimal 1y los devuelve porque el tipo y el valor son los mismos true.

Cabe señalar que NaNno es igual a ningún valor (incluido él mismo). Además, positivo 0es igual a negativo 0.

NaN === NaN  // false
+0 === -0 // true

(3) Valor de tipo compuesto

Al comparar datos de dos tipos compuestos (objetos, matrices, funciones), no se trata de comparar si sus valores son iguales, sino de comparar si apuntan a la misma dirección.

{
    
    } === {
    
    } // false
[] === [] // false
(function () {
    
    } === function () {
    
    }) // false

El código anterior compara dos objetos vacíos, dos matrices vacías y dos funciones vacías respectivamente, y los resultados no son iguales. La razón es que para los valores de tipo compuesto, la operación de igualdad estricta compara si se refieren a la misma dirección de memoria, mientras que los valores de objetos vacíos, matrices vacías y funciones vacías en ambos lados del operador se almacenan en memoria diferente. direcciones El resultado es, por supuesto false.

Dos variables son iguales si se refieren al mismo objeto.

var v1 = {
    
    };
var v2 = v1;
v1 === v2 // true

Tenga en cuenta que para comparaciones entre dos objetos, el operador de igualdad estricta compara direcciones, mientras que el operador mayor o menor que compara valores.

var obj1 = {
    
    };
var obj2 = {
    
    };

obj1 > obj2 // false
obj1 < obj2 // false
obj1 === obj2 // false

De las tres comparaciones anteriores, las dos primeras comparan valores y la última compara direcciones, por lo que ambas se devuelven false.

(4) indefinido y nulo

undefinedy son nullestrictamente iguales a ellos mismos.

undefined === undefined // true
null === null // true

Dado que el valor predeterminado después de declarar una variable es undefined, dos variables que solo se declaran pero no se les asigna un valor son iguales.

var v1;
var v2;
v1 === v2 // true

operador de desigualdad estricta

El operador de igualdad estricta tiene un "operador de desigualdad estricta" correspondiente ( !==). Su algoritmo consiste en encontrar primero el resultado del operador de igualdad estricta y luego devolver el valor opuesto.

1 !== '1' // true
// 等同于
!(1 === '1')

En el código anterior, el signo de exclamación !se utiliza para encontrar el valor opuesto de la siguiente expresión.

operador de igualdad

El operador de igualdad funciona exactamente igual que el operador de igualdad estricta cuando se utiliza para comparar datos del mismo tipo.

1 == 1.0
// 等同于
1 === 1.0

Al comparar datos de diferentes tipos, el operador de igualdad primero convertirá el tipo de datos y luego lo comparará con el operador de igualdad estricta. A continuación se dividen varias situaciones para analizar las reglas para comparar diferentes tipos de valores entre sí.

(1) Valor de tipo primitivo

Los valores de tipo primitivo se convierten en valores numéricos y se comparan.

1 == true // true
// 等同于 1 === Number(true)

0 == false // true
// 等同于 0 === Number(false)

2 == true // false
// 等同于 2 === Number(true)

2 == false // false
// 等同于 2 === Number(false)

'true' == true // false
// 等同于 Number('true') === Number(true)
// 等同于 NaN === 1

'' == 0 // true
// 等同于 Number('') === 0
// 等同于 0 === 0

'' == false  // true
// 等同于 Number('') === Number(false)
// 等同于 0 === 0

'1' == true  // true
// 等同于 Number('1') === Number(true)
// 等同于 1 === 1

'\n  123  \t' == 123 // true
// 因为字符串转为数字时,省略前置和后置的空格

El código anterior convierte cadenas y valores booleanos en valores numéricos y luego los compara.

(2) Comparación de objetos y valores de tipo primitivo.

Cuando un objeto (aquí se refiere a un objeto generalizado, incluidas matrices y funciones) se compara con un valor de un tipo primitivo, el objeto se convierte en un valor de tipo primitivo y luego se compara.

Específicamente, primero llame valueOf()al método del objeto, y si obtiene el valor del tipo original, compárelo de acuerdo con las reglas de la sección anterior; si aún obtiene el objeto, llame al método nuevamente, obtenga la forma de cadena toString(), y luego comparar.

A continuación se muestra un ejemplo de cómo comparar una matriz con un valor de tipo primitivo.

// 数组与数值的比较
[1] == 1 // true

// 数组与字符串的比较
[1] == '1' // true
[1, 2] == '1,2' // true

// 对象与布尔值的比较
[1] == true // true
[2] == true // false

En el ejemplo anterior, el motor JavaScript primero llamará al método de matriz [1]en la matriz valueOf(). Dado que la matriz devuelta sigue siendo una matriz, luego llamará al toString()método de matriz para obtener la forma de cadena y luego la comparará de acuerdo con las reglas en el sección previa.

He aquí un ejemplo más directo.

const obj = {
    
    
  valueOf: function () {
    
    
    console.log('执行 valueOf()');
    return obj;
  },
  toString: function () {
    
    
    console.log('执行 toString()');
    return 'foo';
  }
};

obj == 'foo'
// 执行 valueOf()
// 执行 toString()
// true

En el ejemplo anterior, objes un objeto con un método valueOf()personalizado toString(). Cuando este objeto 'foo'se compara con una cadena, los métodos valueOf()y toString()se llamarán a su vez y finalmente se devolverán 'foo', por lo que el resultado de la comparación es true.

(3) indefinido y nulo

undefinedy nullsolo se devolverán cuando se comparen entre sí o entre sí true; cuando se comparen con valores de otros tipos, el resultado es false.

undefined == undefined // true
null == null // true
undefined == null // true

false == null // false
false == undefined // false

0 == null // false
0 == undefined // false

(4) Desventajas del operador de igualdad

La conversión de tipos oculta por el operador de igualdad puede generar algunos resultados contrarios a la intuición.

0 == ''             // true
0 == '0'            // true

2 == true           // false
2 == false          // false

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Las expresiones anteriores son diferentes de la intuición y es fácil cometer errores. Por lo tanto se recomienda no utilizar el operador de igualdad ( ==), es mejor utilizar sólo el operador de igualdad estricta ( ===).

operador de desigualdad

El operador de igualdad tiene un "operador de desigualdad" correspondiente ( !=), su algoritmo es encontrar primero el resultado del operador de igualdad y luego devolver el valor opuesto.

1 != '1' // false

// 等同于
!(1 == '1')

3. Operadores booleanos (operadores lógicos)

Los operadores booleanos se utilizan para convertir expresiones en valores booleanos. Hay cuatro operadores en total.

  • operador de negación:!
  • Y (y) operador:&&
  • u operador:||
  • Operador ternario:?:

operador de negación (!)

El operador de negación es un signo de exclamación y se utiliza para cambiar un valor booleano a su valor opuesto, es decir, truea false, falsea true.

!true // false
!false // true

Para valores no booleanos, el operador de negación los convierte en valores booleanos. Se puede recordar de esta manera: los siguientes seis valores están invertidos truey todos los demás valores están invertidos false.

  • undefined
  • null
  • false
  • 0
  • NaN
  • cadena vacía ( '')
!undefined // true
!null // true
!0 // true
!NaN // true
!"" // true

!54 // false
!'hello' // false
![] // false
!{
    
    } // false

En el código anterior, no importa qué tipo de valor, después de la operación de inversión, se convierte en un valor booleano.

Si realiza dos operaciones de inversión consecutivas sobre un valor, equivale a convertirlo al valor booleano correspondiente, que tiene el Booleanmismo efecto que una función. Este es un método de conversión de tipos comúnmente utilizado.

!!x
// 等同于
Boolean(x)

En el código anterior, no importa xqué tipo de valor sea, después de dos operaciones de negación, se convierte en el Booleanmismo valor booleano que el resultado de la función. Entonces, negar dos veces es una forma sencilla de convertir un valor en un valor booleano.

Y operador (&&)

Y el operador ( &&) se utiliza a menudo para evaluar múltiples expresiones.

Sus reglas de operación son: si el valor booleano del primer operador es true, entonces se devuelve el valor del segundo operador (tenga en cuenta que es un valor, no un valor booleano); si el valor booleano del primer operador es, falseentonces se devuelve directamente El valor del primer operador y el segundo operador ya no se evalúa.

't' && '' // ""
't' && 'f' // "f"
't' && (1 + 2) // 3
'' && 'f' // ""
'' && '' // ""

var x = 1;
(1 - 1) && ( x += 1) // 0
x // 1

En el último ejemplo del código anterior, dado que el valor booleano del primer operador del operador AND es false, su valor se devuelve directamente 0sin evaluar el segundo operador, por lo que xel valor de la variable no cambia.

Este mecanismo de saltarse el segundo operador se denomina "cortocircuito". A algunos programadores les gusta usarlo para reemplazar ifestructuras. Por ejemplo, el siguiente ifcódigo para una estructura se puede reescribir usando el operador AND.

if (i) {
    
    
  doSomething();
}

// 等价于

i && doSomething();

Las dos formas de escribir el código anterior son equivalentes, pero la última no es fácil de ver y no es fácil de depurar, se recomienda usarla con precaución.

falseY los operadores se pueden utilizar junto con varios operadores. En este caso, se devuelve el valor de la expresión cuyo primer valor booleano se devuelve . Si todas las expresiones tienen un valor booleano true, se devuelve el valor de la última expresión.

true && 'foo' && '' && 4 && 'foo' && true
// ''

1 && 2 && 3
// 3

En el código anterior, en el Ejemplo 1, la primera falseexpresión con un valor booleano es la tercera expresión, por lo que se obtiene una cadena vacía. En el segundo ejemplo, todas las expresiones tienen valores booleanos true, por lo que se devuelve el valor de la última expresión 3.

Operador O (||)

El operador O ( ||) también se utiliza para evaluar múltiples expresiones. Sus reglas de operación son: si el valor booleano del primer operador es true, entonces se devuelve el valor del primer operador y el segundo operador ya no se evalúa; si el valor booleano del primer operador es false, devuelve el valor del segundo operador.

't' || '' // "t"
't' || 'f' // "t"
'' || 'f' // "f"
'' || '' // ""

A este operador también se le aplican las reglas de cortocircuito.

var x = 1;
true || (x = 2) // true
x // 1

En el código anterior, el primer operador del operador OR es true, por lo que regresa directamente truesin ejecutar el segundo operador. Por tanto, xel valor de no ha cambiado. Este mecanismo de controlar si se ejecuta la segunda expresión sólo a través del valor de la primera expresión se denomina "atajo".

El operador OR se puede utilizar varias veces, en cuyo caso se devuelve trueel valor de la expresión con el primer valor booleano. Si todas las expresiones son false, se devuelve el valor de la última expresión.

false || 0 || '' || 4 || 'foo' || true
// 4

false || 0 || ''
// ''

En el código anterior, en el Ejemplo 1, la primera trueexpresión con un valor booleano de es la cuarta expresión, por lo que se obtiene el valor 4. En el Ejemplo 2, los valores booleanos de todas las expresiones son false, por lo que se devuelve el valor de la última expresión.

El operador OR se utiliza a menudo para establecer un valor predeterminado para una variable.

function saveText(text) {
    
    
  text = text || '';
  // ...
}

// 或者写成
saveText(this.text || '')

El código anterior indica que si no se proporciona ningún parámetro cuando se llama a la función, el parámetro se establecerá en una cadena vacía de forma predeterminada.

Operador condicional ternario (?:)

El operador condicional ternario consta de un signo de interrogación (?) y dos puntos (:), que separan tres expresiones. Es el único operador en el lenguaje JavaScript que requiere tres operadores. Si el valor booleano de la primera expresión es true, entonces se devuelve el valor de la segunda expresión; de lo contrario, se devuelve el valor de la tercera expresión.

't' ? 'hello' : 'world' // "hello"
0 ? 'hello' : 'world' // "world"

Los valores booleanos de las sumas en el código tanterior 0son respectivamente truesuma false, por lo que los valores de la segunda y tercera expresión se devuelven respectivamente.

En términos generales, las expresiones condicionales ternarias if...elsetienen el mismo efecto de expresión que las oraciones, y lo que las primeras pueden expresar, las segundas también lo pueden expresar. Pero hay una diferencia importante entre las dos: if...elsees una declaración y no tiene valor de retorno; la expresión condicional ternaria es una expresión y tiene un valor de retorno. Por lo tanto, cuando se requiere un valor de retorno, solo se pueden usar expresiones condicionales ternarias, no if..else.

console.log(true ? 'T' : 'F');

En el código anterior, console.logel parámetro del método debe ser una expresión, entonces solo se pueden usar expresiones condicionales ternarias. Si desea utilizar if...elseuna declaración, debe cambiar todo el texto del código.

4. Operadores de bits

El operador bit a bit convierte el operando en un entero binario de 32 bits y luego realiza operaciones en cada bit. Por ejemplo:

Los 32 bits de 5 son:

00000000000000000000000000000101

Los 32 bits de 100 son:

00000000000000000000000001100100

Los 32 bits de 15 son:

00000000000000000000000000001111

Bit a bit NO

El operador NOT bit a bit ~convierte el número en un entero binario de 32 bits y luego invierte cada bit. Todos los 1 se convierten en 0 y todos los 0 se convierten en 1

Por ejemplo:

Los 32 bits de 5 son:

00000000000000000000000000000101

32 bits de ~5 son:

11111111111111111111111111111010  

El valor convertido es -6

Bit a bit NO, esencialmente niega el operando y luego resta 1.

Bit a bit Y

El operador OR bit a bit &convierte dos números en un entero binario de 32 bits y realiza una operación AND bit a bit en cada bit de los dos números. Las reglas para AND bit a bit son las siguientes:

primer número segundo numero resultado
1 1 1
1 0 0
0 1 0
0 0 0

Ejemplo concreto:

console.log(12 & 10); // 8

La representación binaria de 32 bits de 12 es: 1100
La representación binaria de 32 bits de 10 es: 1010

El resultado del AND bit a bit es: 1000

O bit a bit

El operador OR bit a bit |convierte dos números en un entero binario de 32 bits y realiza una operación OR bit a bit en cada bit de los dos números. Las reglas para OR bit a bit son las siguientes:

primer número segundo numero resultado
1 1 1
1 0 1
0 1 1
0 0 0

Ejemplo concreto:

console.log(12 | 10); // 14

La representación binaria de 32 bits de 12 es: 1100
La representación binaria de 32 bits de 10 es: 1010

El resultado de OR bit a bit es: 1110

XOR bit a bit

El operador OR bit a bit ^convierte dos números en enteros binarios de 32 bits y realiza una operación XOR bit a bit en cada bit de los dos números. La regla de operación es que si los dos bits son diferentes, se devolverá 1, y si los dos bits son iguales, se devolverá 0, como se muestra en la siguiente tabla:

primer número segundo numero resultado
1 1 0
1 0 1
0 1 1
0 0 0

Ejemplo concreto:

console.log(12 ^ 10); // 6

La representación binaria de 32 bits de 12 es: 1100
La representación binaria de 32 bits de 10 es: 1010

El resultado de XOR bit a bit es: 0110

Si XOR bit a bit es un valor no entero, si solo uno de los dos operandos es verdadero, devuelve 1. Si ambos operandos son verdaderos o ambos son falsos, devuelve 0. El ejemplo es el siguiente:

console.log(true ^ "Hello"); // 1
console.log(false ^ "Hello"); // 0
console.log(true ^ true); // 0
console.log("Hello" ^ "Hello"); // 0
console.log(false ^ false); // 0
console.log(true ^ false); // 1

Tenga en cuenta que Hola aquí se convierte a NaN

desplazamiento bit a bit

Los operadores de desplazamiento bit a bit <<y >>desplazarán todos los bits hacia la izquierda o hacia la derecha en una cantidad específica, multiplicando o dividiendo efectivamente un número por una potencia específica de 2.

<<: Multiplicar por 2 a la potencia especificada

console.log(2<<2); // 8

2 por 2 elevado a la potencia 2

00000010 convertido a 00001000

>>: Dividir por 2 a la potencia especificada

console.log(16>>1); // 8

16 dividido por 2 elevado a 1

00010000 se convierte en 00001000

5. Otros operadores

operador nulo

La función del operador void es ejecutar una expresión y luego no devolver ningún valor o devolver undefined .

void 0 // undefined
void(0) // undefined

Las anteriores son dos formas de escribir el operador nulo, las cuales son correctas. Se recomienda la última forma, es decir, utilizar siempre paréntesis.

Debido a que el operador de anulación tiene una alta prioridad, si no se utilizan paréntesis, es fácil generar resultados incorrectos.

Por ejemplo, "void 4 + 7" en realidad es equivalente a "(void 4) + 7" .

A continuación se muestra un ejemplo de operador nulo .

var x = 3;
void (x = 5) //undefined
x // 5

El objetivo principal de este operador es la herramienta de marcadores del navegador ( Bookmarklet ) y la inserción de códigos en hipervínculos para evitar saltos de páginas web.

Consulte el código a continuación.

<script>
function f() {
    
    
  console.log('Hello World');
}
</script>
<a href="http://example.com" onclick="f(); return false;">点击</a>

En el código anterior, después de hacer clic en el enlace, el código onclick se ejecutará primero . Dado que onclick devuelve false , el navegador no saltará a example.com .

El operador nulo puede reemplazar la escritura anterior.

<a href="javascript: void(f())">文字</a>

El siguiente es un ejemplo más práctico: el usuario hace clic en el enlace para enviar el formulario, pero no se produce ningún salto de página.

<a href="javascript: void(document.form.submit())">
  提交
</a>

operador de coma

El operador de coma evalúa dos expresiones y devuelve el valor de la última expresión.

'a', 'b' // "b"

var x = 0;
var y = (x++, 10);
x // 1
y // 10

En el código anterior, el operador coma devuelve el valor de la última expresión.

Un uso del operador de coma es realizar algunas operaciones auxiliares antes de devolver un valor.

var value = (console.log('Hi!'), true);
// Hi!

value // true

En el código anterior, primero se realiza la operación antes de la coma y luego se devuelve el valor después de la coma.

6. Orden de operación

prioridad

La precedencia ( Precedencia del operador ) de varios operadores en JavaScript es diferente. Los operadores con mayor precedencia se ejecutan primero y los operadores con menor precedencia se ejecutan después.

4 + 5 * 6 // 34

En el código anterior, el operador de multiplicación ( * ) tiene mayor prioridad que el operador de suma ( + ), por lo que primero se realiza la multiplicación y luego se realiza la suma, lo que equivale a lo siguiente.

4 + (5 * 6) // 34

Si se mezclan varios operadores, a menudo se produce un código confuso.

var x = 1;
var arr = [];

var y = arr.length <= 0 || arr[0] === undefined ? x : arr[0];

En el código anterior, el valor de la variable y es difícil de ver porque esta expresión involucra 5 operadores y no es fácil recordar cuál tiene la mayor prioridad.

Según la especificación del lenguaje, la precedencia de estos cinco operadores de mayor a menor es: menor o igual a ( <= ), igualdad estricta ( === ) o ( || ), ternario ( ?: ), signo igual ( = ). Por lo tanto, el orden real de operaciones para la expresión anterior es el siguiente.

var y = ((arr.length <= 0) || (arr[0] === undefined)) ? x : arr[0];

Recordar la precedencia de todos los operadores es difícil e innecesario.

La función de los paréntesis.

Los paréntesis se pueden utilizar para aumentar la prioridad de una operación, porque su prioridad es la más alta, es decir, la expresión entre paréntesis se evaluará primero.

(4 + 5) * 6 // 54

En el código anterior, debido al uso de paréntesis, la suma se realizará antes de la multiplicación.

Los niveles de prioridad de los operadores son muy complicados y tienen reglas rígidas, por lo que se recomienda utilizar siempre paréntesis para garantizar que el orden de las operaciones sea claro y legible, lo cual es crucial para el mantenimiento y la depuración del código.

Por cierto, los paréntesis no son operadores, sino una construcción de sintaxis. Tiene dos usos: uno es poner la expresión entre paréntesis para aumentar la prioridad de la operación; el otro es seguir la función para llamar a la función.

Tenga en cuenta que, como los paréntesis no son operadores, no tienen ningún efecto de evaluación y solo cambian la prioridad de la operación.

var x = 1;
(x) = 2;

En la segunda línea del código anterior, si los paréntesis tienen un efecto de evaluación, se convertirá en 1 = 2 , lo que provocará un error. Sin embargo, el código anterior funciona, que verifica que los paréntesis solo cambian la prioridad, no la evaluación.

Esto también significa que si la expresión completa está entre paréntesis, no tiene ningún efecto.

(expression)
// 等同于
expression

Poner una función entre paréntesis devuelve la función misma. Si los paréntesis siguen inmediatamente a la función, significa llamar a la función.

function f() {
    
    
  return 1;
}

(f) // function f(){return 1;}
f() // 1

En el código anterior, la función colocada entre paréntesis devolverá la función en sí, y los paréntesis que siguen a la función llamarán a la función.

Solo se pueden colocar expresiones entre paréntesis. Si se coloca una declaración entre paréntesis, se informará un error.

(var a = 1)
// SyntaxError: Unexpected token var

asociativo de izquierda y asociativo de derecha

Para operadores con el mismo nivel de precedencia, cuando aparezcan al mismo tiempo, habrá un problema de orden de cálculo.

a OP b OP c

En el código anterior, OP representa operador. Se puede interpretar de dos maneras.

// 方式一
(a OP b) OP c

// 方式二
a OP (b OP c)

Los resultados de los cálculos obtenidos mediante los dos métodos anteriores suelen ser diferentes.

El primer método consiste en combinar los dos operandos del lado izquierdo. El operador que utiliza este método de interpretación se denomina operador de " asociatividad de izquierda a derecha " ;

El segundo método consiste en combinar los dos operandos del lado derecho, lo que se denomina operador de " asociatividad de derecha a izquierda " .

La mayoría de los operadores en el lenguaje JavaScript son "asociativos por izquierda", consulte el ejemplo del operador de suma a continuación.

x + y + z

// 引擎解释如下
(x + y) + z

En el código anterior, x e y se combinan y sus resultados presupuestarios se calculan con z .

Algunos operadores son "asociativos derechos", los más importantes de los cuales son el operador de asignación ( = ) y el operador condicional ternario ( ?: ).

w = x = y = z;
q = a ? b : c ? d : e ? f : g;

El código anterior se explica a continuación.

w = (x = (y = z));
q = a ? b : (c ? d : (e ? f : g));

Las dos líneas de código anteriores combinan los operandos del lado derecho.

Además, el operador de exponenciación (**) también es asociativo derecho.

2 ** 3 ** 2
// 相当于 2 ** (3 ** 2)
// 512

Respuestas a preguntas reales

  • En el siguiente código, ¿ bajo qué circunstancias a ejecutará la declaración de salida e imprimirá 1 ?
var a = ?;
if(a == 1 && a == 2 && a == 3){
    
    
 	console.log(1);
}

Respuesta de referencia:

Método 1: utilizar el método toString()

var a = {
     
     
    i: 1,
    toString() {
     
     
        return a.i++;
    }
}
if (a == 1 && a == 2 && a == 3) {
     
     
    console.log('1');
}

Método 2: utilizar el método valueOf()

var a = {
     
     
    i: 1,
    valueOf() {
     
     
        return a.i++
    }
}
if (a == 1 && a == 2 && a == 3) {
     
     
    console.log('1');
}

- EOF -

Supongo que te gusta

Origin blog.csdn.net/qq_53461589/article/details/132739427
Recomendado
Clasificación