理解js代码expression式
var PgrtiJr = { "TWfbR": +((!+[] + !![] + !![] + !![] + []) + (!+[] + !![] + !![])) }; PgrtiJr.TWfbR -= +((+!![] + []) + (+!![])); console.log(parseInt(PgrtiJr.TWfbR, 10));
我有上面提到的JS代码。 我在http://math.chapman.edu/~jipsen/js/上执行了这个代码。 有人能解释一下,它是如何等于32
?
你能推荐任何可以在python中评估这个expression式的python库吗?
尝试execjs,但没有运气
您需要了解一些关于JavaScript宽松input的重要内容。 让我们从更简单的事情开始,具体到你的问题。
-
一个空的数组文字被认为是真实的,但是当你应用一元+运算符,数组将被转换为一个string,然后将被转换为一个数字。 所以,内部
+[]
评估为0。console.log(+[]); // 0
-
由于
[]
是truthy,所以用逻辑not操作符否定它会给你true
,当在算术expression式中使用时,求值为1,因为1大致等于true
。console.log(!![], 3 + !![]); // true 4
-
除了所有这些,当我们使用带有
+
运算符的数组文本时,数组将被转换为string,并且由于expression式的一部分是string,expression式的另一部分也将被转换为string并且string连接发生。 所以得到的对象将是stringtypes。console.log(typeof 1, typeof [], typeof (1 + []), 1 + []); // number object string 1
有了这个基本的认识,让我们先分析一下expression式。
+((!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]))
让我们先拿,
(!+[]+!![]+!![]+!![]+[])
在这里, +[]
计算结果为0
而逻辑不true
。 因为我们在一个带有数字操作数的expression式中使用它,所以true
被视为1.并且根据我们上面看到的第二点, !![]
计算为1.因此,expression式变成1 + 1 + 1 + 1 + []
,其实是4 + []
。 而根据第3点,数字4将变成弦4。
同样的,expression式的其他部分(!+[]+!![]+!![])
变成1 + 1 + 1
,其实是3,所以当你做'4' + 3
,会得到'43'
,这是一个string。 现在,我们有一个一元+运算符,它将这个string转换为一个数字。 所以,这个expression式的评估结果变成了43,这是一个数字。
expression的另一部分,
PgrtiJr.TWfbR -= +((+!![]+[])+(+!![]))
将会这样评价
+((1 + []) + 1)
接着
+('1' + 1)
接着
+'11'
然后评估为11.由于PgrtiJr.TWfbR
实际上是43,所以43 – 11变成了32.这就是为什么你得到了32的答案。
[] is an object that is equal to null. !![] is a "boolean" that equals to true. (twice ! of null ( = false) ) !+[] is a "boolean" that equals to true.
如果我们在这个expression式之后添加一个[],它们将被转换为string。
所以(!+[]+!![]+!![]+!![]+[])
将是一个等于4的string
(!+[]+!![]+!![])
将是一个等于3的string
因此(!+[]+!![]+!![]+!![]+[]) + (!+[]+!![]+!![])
将是一个等于43
和+(!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![])
将是一个数字, 43
+((+!![]+[])+(+!![]))
等于11
所以总的expression等于43 – 11 = 32