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 :
++x
ox++
- Operador de decremento :
--x
ox--
- 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, obj
el valor del objeto convertido al tipo original es [object Object]
y, cuando se agrega, 2
se 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 valueOf
se llaman automáticamente.
var obj = {
p: 1 };
obj.valueOf() // { p: 1 }
En términos generales, el valueOf
método del objeto siempre devuelve el objeto en sí, en este momento el método del objeto se llama automáticamente toString
y se convierte en una cadena.
var obj = {
p: 1 };
obj.valueOf().toString() // "[object Object]"
Los métodos del objeto toString
regresan 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 valueOf
métodos o toString
métodos para obtener los resultados deseados.
var obj = {
valueOf: function () {
return 1;
}
};
obj + 2 // 3
En el código anterior, definimos el método obj
del 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.valueOf
1
obj + 2
3
valueOf
toString
A continuación se muestra un ejemplo de un toString
método personalizado.
var obj = {
toString: function () {
return 'hello';
}
};
obj + 2 // "hello2"
En el código anterior, el método obj
del objeto toString
devuelve 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 Date
instancia de un objeto, toString
el 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 obj
es una instancia de un objeto, los métodos y métodos Date
están personalizados y el método resultante se ejecuta primero.valueOf
toString
toString
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 x
aumenta y luego regresa 2
, y luego disminuye y regresa 1
. Ambos casos harán que x
el 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, x
el valor actual se devuelve primero y luego se incrementa, por lo que obtenemos 1
; y
primero 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 ( Number
lo 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 NaN
tambié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 2
si es mayor que o no 1
y 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 c
punto de código Unicode en minúscula ( 99
) es mayor que el C
punto 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 NaN
la comparación con. Se devuelve cualquier valor (incluido NaN
él mismo) que NaN
se 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 valueOf
al método; si el objeto devuelto sigue siendo un objeto, entonces llamar al toString
mé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 1
con la cadena "1" y el valor booleano true
con 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 1
y hexadecimal 1
y los devuelve porque el tipo y el valor son los mismos true
.
Cabe señalar que NaN
no es igual a ningún valor (incluido él mismo). Además, positivo 0
es 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
undefined
y son null
estrictamente 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, obj
es 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
undefined
y null
solo 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, true
a false
, false
a 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 true
y 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 Boolean
mismo 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 x
qué tipo de valor sea, después de dos operaciones de negación, se convierte en el Boolean
mismo 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, false
entonces 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 0
sin evaluar el segundo operador, por lo que x
el valor de la variable no cambia.
Este mecanismo de saltarse el segundo operador se denomina "cortocircuito". A algunos programadores les gusta usarlo para reemplazar if
estructuras. Por ejemplo, el siguiente if
có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.
false
Y 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 false
expresió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 true
sin ejecutar el segundo operador. Por tanto, x
el 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 true
el 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 true
expresió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 t
anterior 0
son respectivamente true
suma 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...else
tienen 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...else
es 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.log
el parámetro del método debe ser una expresión, entonces solo se pueden usar expresiones condicionales ternarias. Si desea utilizar if...else
una 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 -