这段代码是如何工作的?如果可能的话,我想要一个详细的解释,并想知道哪里有关于它的文档。
if (!+[]+!+[] == 2) {
document.write('Somos iguales');
}
else {
document.write('Somos distintos');
}
这段代码是如何工作的?如果可能的话,我想要一个详细的解释,并想知道哪里有关于它的文档。
if (!+[]+!+[] == 2) {
document.write('Somos iguales');
}
else {
document.write('Somos distintos');
}
一个
Array
空等于false
相反的
false
是true
true
等于 1false
等于 0然后
JSFuck
是一种基于JavaScript原子部分的深奥且具有教育意义的编程风格。要记住的一些规则:
转换
!
为值之前Booleano
在我们
+
转换为数字之前加法
[]
转换为字符串!+[]
通过将加号放在它变成数字之前, 0+[] = 0
的否定(!)
是1。然后当执行总和
!+[] + !+[]
时1+1 = 2
参考
下面列出的是对应于每个主要部分的参考
哪个是
[]
用于初始化数组类型的对象字面量的表达式,相当于new Array()
.+[]
具有一元运算符 + 的矩阵。!+[]
具有一元运算符 + 和非逻辑一元运算符的矩阵。!+[] + !+[]
加了两个!+[]
。!+[] + !+[] == 2
两者相加的抽象比较!+[]
。让我们开始吧
[]
数组字面量。数组的长度属性 (length
) 为零。原始值是一个空字符串。有关更多详细信息,请参阅基于 ECMAScript 2016(第 7 版)的 [] 的原始值是什么?.在Unary + operator 1中,表明它将
+
其操作数转换为数字类型。在 的情况下+ []
,操作数是一个空字符串([].join() === ''
在 Chrome 控制台中测试返回true
)并将其转换为数字会转换为0
.在逻辑运算符 not 1中表示
!
将其操作数转换为布尔类型,如果操作数的布尔值为 false,则返回 true,如果操作数的布尔值为 true,则返回 false。在ToBoolean 1中,表示当值为零(
-0
或+0
)时,返回 false(false
)。在加法运算符 ( + ) 1中表明,当操作数的类型不是文本字符串时,它们将转换为数字。
ToNumber 1表示当值为真时,返回一( ),当值为假时,返回零( )。
1
0
En Applying the Additive Operators to Numbers1 se indica que cuando
+
se aplica a dos operandos numéricos, realiza la adición de estos.En Abstract equality comparison1 se indica que cuando los dos elementos a la izquierda y derecha son iguales, devuelve verdadero (
true
)y en caso contrario devuelve falso (false
).Entonces
+[]
es una operación unitaria que devuelve cero (0
)!0
es una operación unitaria que devuelve verdadero (true
)true + true
es una operación que, primero convierte cada operando a1
y luego devuelve su adición la cual es2
2 == 2
es una comparación de igualdad abstracta que devuelve verdadero (true
)A continuación un pequeño experimento para que el lector compruebe si stack-snippet y su navegador operan conforme a la especificación referida.
为了补充答案,让我们考虑以下系列中记录的附加元素:
1) JavaScript 原始数据和复杂数据:
JavaScript 基于 ECMAScript 的数据类型,分为原始和复杂或引用:
原始数据:
字符串:unicode、ascii 和字母数字字符。
数字:整数,浮点数。
布尔值:真假。
空:空。
未定义:未定义。
复杂数据:
2)数据的布尔值:
原始数据:
var string="Hola soy una string";
将返回true
。var integer=123;
将返回true
。var trueVariable = true;
将返回true
。var float = 4.98;
将返回真。复杂数据:
var arraySinElementos = [];
将返回true
。var arrayConElementos = [0,1,2];
将返回true
。例外:
根据上述表格,我们可以通过应用找到以下数据类型的布尔值
ToBoolean()
:Boolean false:将返回
false
。数字零:将返回 false。
未定义:将返回 false。
Null:将返回 false。
2) 逻辑运算符的值:
我们定义了主要的逻辑值:
逻辑运算符
not (!)
:应用接收值的倒数。它的操作如下:
表达式将使用 a 进行评估
ToBoolean()
,它将遵循下表:应用逆我们将有:
在是表达式的情况下,
true
它将返回false
。在存在的情况下,将被
false
退回true
。如果它不为零 (
!==0
),则结果为零。如果为 0,则结果为 1。
如果可能,字符串将转换为数字。
空字符串转换为
true
.逻辑值 null 或 not 执行确定的动作
false
,因为不知道条件是否为真。3)一元加运算符(+表达式)和加法加运算符(表达式+表达式):
加号 (+) 运算符可以作为一元和加法运算符找到:
此函数将应用于
ToNumber()
表达式:如果它用于非数字值,它将应用函数
ToNumber()
,在我们的例子中,我们有一个array[]
将输入引用数据或Object
.换句话说,它将
ToNumber()
应用于 aobject
,因此使用ToPrimitive()
.4)功能
ToPrimitive()
:这个函数可以在类型转换部分找到:
它将用于将对象转换
Object
为原始值,以便以后可以通过以下方式对其进行评估:分别。
在这种情况下,作为 Object
Object
: 适用:遵循以下评估顺序:
汇总表:
转换进行:
在这种情况下,它是一个
string vacio
.履行:
应用“
toString()
”,然后“valueOf()
”申请我们有:
所以:
+[] == ToNumber(数组[])。
ToNumber(array[]) == ("").valueOf().
("").valueOf == ("")。
现在让我们使用我们的逻辑运算符 not (!) 来获得:
5)接下来是时候更换了:
解决:
结尾:
Veo que esta pregunta ha generado un grupo de respuestas muy valiosas y es este tipo de preguntas y respuestas las que más nutren a nuestra comunidad. Intentaré aportar mi granito de arena a este maravilloso hilo.
Voy a aclarar ciertos aspectos que no están aclarados. Quien lea las respuestas notará que hay algunas que se contradicen. He visto un comentario de @toledano en la respuesta de @Dev.Joel y otra de @Dev.Joel en la respuesta de @JorgeArturoJuarez básicamente preguntándose por qué
[] == false
estrue
y por otro lado![]
esfalse
y me parece que es debido a varias de las respuestas que son algo ambiguas, como la respuesta marcada como correcta que mostraba que[]
era igual afalse
.Lo primero que hay que saber es que toda instancia de un objeto está definida de por sí y por lo tanto es verdadera:
No se deben confundir las instancias de un objeto con los valores primitivos:
Sin embargo al usar los operadores de comparación (exceptuando
===
y!==
) y los operandos tener un tipado diferente,JavaScript
intenta convertir ambos operandos a un tipo apropiado para realizar la comparación, y generalmente esta conversión es numérica. Es por eso que ocurre lo siguiente sin importar que sean instancias de objetos y sean verdaderas:Teniendo esto en cuenta se podrá entender por qué
[] == false
datrue
y![]
dafalse
.En cuanto a la pregunta principal, ya todo está más que explicado en las anteriores respuestas, aquí lo resumo:
+
a una instancia deArray
vacía el resultado es0
(ya que internamente le aplica la operación abstractaToNumber
).!
a0
el resultado estrue
(ya que este operador devuelvefalse
si la expresión puede ser evaluada atrue
y en caso contrario devuelvetrue
)true
el resultado será2
(ya que al no tratarse de cadenas de caracteres, en vez de concatenar, el operador intentará convertir los operandos a número antes de sumarlos)