JS FUCK学习
[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((+{}+[])[+!![]]+(![]+[])[!+[]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]))[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![])([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]))[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![])(([]+{})[+[]])[+[]]+(!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[]))+(+!![]+[])+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]))[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![])([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]))[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![])(([]+{})[+[]])[+[]]+(!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])))(+[])
当你看到这样一长串字符组成的代码时,心中会有多少只草泥马飘过?
WTF?这什么玩意儿?
答:这是一段JS代码。
JS的数据类型
js的数据类型分为基本(简单)数据类型和引用(复杂)数据类型
基本数据类型
基本数据类型有7种了
null、undefined、boolean、number、string、symbol、bigint
symbol
主要用作唯一值
bigInt
number的范围为-(2^53 - 1) ~2^53 - 1 ,不在这个范围的数值会丢失精度。
9007199254740992 === 9007199254740993; // → true
bigInt解决了这个问题,我们只需要在数值末尾加上n,或者使用BigInt()构造函数处理这个数。
引用数据类型
object(包含function、Array、Date等)
typeof 的返回值
typeof返回的值有undefined、boolean、number、string、symbol、bigint、function、object
null去哪了
typeof null // object
这是一个历史遗留问题,第一版的JavaScript是用32位比特来存储值的,且是通过值的低1位或3位来识别类型的
- 1:整型(int)
- 000:引用类型(object)
- 010:双精度浮点型(double)
- 100:字符串(string)
- 110:布尔型(boolean)
null的低3位也是000
详见 为什么JavaScript里面typeof(null)的值是"object"?
数据类型转换
当我们执行数字和字符串相加
1 + '1' // '11'
得到的是'11'而不是2
这期间发生了什么?
数字1转换成了字符串1,字符串拼接得到了字符串11
话不多说,先上一张犀牛书上的表
| 值 | 转换为字符串 | 转换为数字 | 转换为布尔值 | 转换为对象 |
|---|---|---|---|---|
| undefined | "undefined" | NaN | false | throw TypeError |
| null | "null" | 0 | false | throw TypeError |
| true | "true" | 1 | new Boolean("true") | |
| false | "false" | 0 | new Boolean("false") | |
| "" | 0 | false | new String("") | |
| "1.2" | 1.2 | true | new String("1.2") | |
| "1.2a" | NaN | true | new String("1.2a") | |
| "aaa" | NaN | true | new String("aaa") | |
| 0 | "0" | false | new Number(0) | |
| -0 | "0" | false | new Number(-0) | |
| 1 | "1" | true | new Number(1) | |
| NaN | "NaN" | false | new Number(NaN) | |
| Infinity | "Infinity" | true | new Number(Infinity) | |
| -Infinity | "-Infinity" | true | new Number(-Infinity) | |
| [] | "" | 0 | true | |
| [9] | "9" | 9 | true | |
| ["a", "b"] | "a,b" | NaN | true |
- 数组类型的类型转换,数组转换为字符串,实际上是调用 join() 方法
- 转为布尔类型成为
false的有:undefined、null、空字符串、0、-0、NaN- 字符串类型转为数值类型:
- 若字符串中出现任意非数字、非空格的字符,均转为NaN
- 若数字中间存在空格,转为NaN
- 若希望尽可能的转换字符串中出现的数字,请参考parseInt、parseFloat方法
- new Number() 和 Number() 是不同的:
- new Number() 创建一个Number对象
- Number() 将传入的参数转换为数值字面量
对象的类型转换
对象到字符串的转换( 这里说的是String()方法的原理 )
- 若具有toString()方法,调用toString(),如果它返回一个原始值,将这个原始值转换为字符串返回
- 若无toString()方法,或toString()的返回值并不是一个原始值,寻找其valueOf()方法,若存在这个方法,调用它,如果它返回一个原始值,将这个原始值转换为字符串返回
- 否则(无valueOf()或valueOf()的返回值不是原始值),JS无法从toString()或valueOf()方法获得一个原始值,因此,throw TypeError
对象到数字的转换(这里说的是Number()方法的原理)
- 若具有valueOf()方法,调用valueOf(),如果它返回一个原始值,将这个原始值转换为数字返回
- 若无valueOf()方法,或valueOf()的返回值并不是一个原始值,寻找其toString()方法,若存在这个方法,调用它,如果它返回一个原始值,将这个原始值转换为数字返回
- 否则(无toString()或toString()的返回值不是原始值),JS无法从toString()或valueOf()方法获得一个原始值,因此,throw TypeError
对象到布尔值的转换
- 对象类型转换为布尔值:均为true,不管其toString()、valueOf()方法返回什么
显式转换
主要通过构造函数将值转换为对应的数据类型
parseInt() 、parseFloat() 、引用数据类型的toString() 也能实现数据类型转换
隐式转换
通过算术运算符或者关系运算符操作两个不同的数据类型可能触发隐式转换
算术运算符(+、-、*、/、++、–、%…)
- '+'作为一个双目运算符: 若+两边存在一个字符串,将另一个也转为字符串进行字符串拼接。
- 其他情况下,不管双目还是单目,都转为数值类型
关系运算符(>、<、==、!=…)
- =、!:同时对比类型和值,两个都为真才返回真
- ==、!=: 若两边均为对象,对比它们的引用是否相同
- 逻辑非(!): 将其后变量或表达式转为布尔值
- 对比字符串:从头至尾扫描逐个比较每个字符的unicode码,直到分出大小
- 其他情况下,两边均转为数值类型
注意:NaN与任何值都不相同,与任何值比较都返回false
对象类型在运算时进行类型转换都先调用 valueOf() 方法,再尝试 toString() 方法
在进行对象字面量(这里说的是JSON格式的对象字面量)运算时要注意,若运算符两边都是字面量,则将它们都视为对象字面量进行类型转换; 若只有一个字面量时要注意,当这个字面量在首位时,会被当做一个块看待。
思考:如何判断对象的值是否相等
常见的隐式转换
{} + {} => "[object Object][object Object]"
[1,2,3] + [] => "1,2,3" + "" ->"1,2,3"
[] + {} => "" + "[object Object]" -> "[object Object]"
{} + [] => 0 ---> {}被当做一个块,相当于执行 ({},+[]),返回值为小括号最后面的表达式的返回值
{q:1} + [] => 0
var a = {q:1};
a + [] => "[object Object]" 变量形式运算正常
[] + a => "[object Object]"
{} == [] => 报错 ({}, ==[])->报错
[] == 0 => true []->""->0
![] == 0 => true ![]->false->0
[] == ![] => true []->""->0 ![]->false->0
[] == [] => false 比较引用地址
{} == {} => false 比较引用地址
{} == !{} => false !{}->false->0 {}->"[object Object]"->NaN
JSfuck基础原理
在这之前,说一个神奇面试题
[] == ![] // true
首先
Boolean([]) // true
Boolean(![]) // false
当然这里不是拿 true 和 false 比较
根据操作符的优先级, ![]首先执行得到 false
接下来就是 [] == false
在相等运算符中,如果运算符两边的值有一个是布尔类型,则会把true转换成1,false则转换为0。
两者同时转换为数字
得 0 === 0
通过[]获取基本数据
![] // false
!![] // true
[][[]] // undefined
+[] // 0
1 + [] // '1'
1 + [0] // '10'
!+[] // true
+true // 1
+!+[] // 1
+!+[] + !+[] // 2
那么数字10怎么获取呢?
+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[] // 10 这样当然可以
// 但是有没有简单的方法呢?
// 我们可以通过字符串拼接得到
+!+[] + [+[]] // '10'
+(+!+[] + [+[]]) // 10
// 如果不使用 () 呢
+[+!+[] + [+[]]] // 10
数字对于我们不是什么事了
就这样我们通过 [] 得到了构造函数
[] // Array
+[] // Number
![] // Boolean
[] + [] // String
通过一个 [] 居然能干这么多事,我们能拿到string,string可以通过下标拿到对应的字符
[] + [![]] // 'false'
[] + [!![]] // 'true'
[][[]] // undefined
[] + [][[]] // 'undefined'
我们可以拿到这么多字符串了耶!
但是还不够
数组有很多方法,我们能通过以上的字符拼接出 fill filter
我们通过
([] + ![])[0] // 'f'
([] + [][[]])[5] // 'i'
([] + [![]])[2] // 'l'
([] + ![])[0] + ([] + [][[]])[5] + ([] + [![]])[2] + ([] + [![]])[2] // 'fill'
[] + []['fill'] // 'function fill() { [native code] }'
现在我们又多了几个字母,是不是可以拼接出 'constructor' 了
接下来
[]['fill']['constructor'] // ƒ Function() { [native code] }
[] + []['fill']['constructor'] // 'Function() { [native code] }'
What? Function构造函数被我们弄出来了!!
实现一个alert(1)吧
先弄出一个字符串的 'alert(1)',然后使用 Function('alert(1)')()
([] + [![]])[1] // 'a'
([] + [![]])[2] // 'l'
([] + [![]])[4] // 'e'
([] + [!![]])[1] // 'r'
([] + [!![]])[0] // 't'
([] + []['fill'])[13] // '('
([] + []['fill'])[14] // ')'
浙公网安备 33010602011771号