序:
我们在js逆向的过程中,会遇到各种各样的代码段。 其中最常见也是最考验基础的便是符号操作。对应的便是数据类型转换问题。
本节课程。我们会正对各类数据类型转换进行讲解。其中包括方法强转, 加减乘除,隐士转换(==)。
在讲解之前,我们做一些前提基础复习。
一, 课前小知识:
undefined, null 和 NaN 的区别
1- undefined:
表示变量已创建,未赋值。 最常见的情形为。 跟值时, 我们在搜索关键字sign时查看sign的值,
发现为undefined。原因为sign还未被赋值,所以为undefined
2- Null:
变量已创建,并赋值为Null,
3- NaN:
不合法数。 两个不可运算的数据类型,做运算操作, 则被视为不合法
另一个课外知识: 表驱动法
表驱动法是一种编程模式,从表里查找信息而不使用逻辑语句(if 和case)。
事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。
对简单的情况而言,使用逻辑语句更为容易和直白,但随着逻辑链的越来越复杂,查表法也就愈发显得更具有吸引力。
二,运算符优先级
三, 类型转换
1- BigInt
创建方式 BigInt('10')
2- undefined, null 和 NaN 的区别
undefined表示已声明未赋值(未定义),是一个数据最原始的状态
举例:var a、var b={};b.x
null表示变量已声明且赋值为null,即值为空值。常用于通过将null赋给变量来清空变量以预防内存泄漏等问题。document.getElementById('A')
NaN和任何数据都不相等,包括NaN本身,其他数据类型和NaN运算的结果都是NaN。undefined + 1。它表示不合法的数,可以通过isNaN()来判断某个值是否为数。
3- Infinity & -Infinity
正无穷和负无穷, 用 === 比较时为ture, 但是他们是两个指向
4- 强转数字
1- 列表
1- 空列表返回数据为0
2- 列表中有且只有一个可被eval成数字的字符,则为eval后的值
3- 其他情况都为NaN
2- 字符串
1- 空字符串为0
2- 如果可以eval成数字, 则为那个值。 无法识别字符串中的计算
3- 布尔值
true为1, false为0
4- undefined 为 NaN
5- Symbol 无法转为数字
6- BigInt去除 'n'
7- 如果是对象转数字, 按照下列优先级取值
Symbol.toPrimitive > valueOf的原始值 > toString
8- 函数可视为对象
4- 强转为字符串
1- 在绝大多数情况下,String底层使用的时候会调用 [val]的toString()方法。但是针对 null/undefined等String() 方法会有特殊的处理。可以视为一种安全的字符串转换方案。
2- 若val是一个原始值,则转换结果直接为字符串即可
3- 若val是一个对象,转换规则如下
先调用对象的Symbol.toPrimitive方法
如果没有Symbol.toPrimitive方法,则调用对象的toString方法将其转换为字符串
5- 强转为布尔值
除0、NaN、空字符串、null、undefined、 false返回的值是false外,其余都是true
6- 强转object
后续学完原型链再补充
四- 隐式转换
1- 符号减乘除和取余(- * / %)
先将二者隐式转为Number
2- 符号加 (+)
+号两边有值则判断两边值的类型,
若两边都为数字则进行数字计算,
若有一边是字符串,就会把另一边也转换为字符串进行连接。
若一边为引用类型,则两边都转换成字符串拼接
3- 符号等 (==)
当使用==进行比较的时候,会有以下转换规则(判断规则):
1. 两边类型如果相同,值相等则相等,如 2 == 3肯定是为false的了
2. 比较的双方都为基本数据类型
a. 若是一方为null、undefined,则另一方必须为null或者undefined才为true,也就是null == undefined为true或者null == null为true,因为undefined派生于null
b. 其中一方为String,是的话则把String转为Number再来比较
c. 其中一方为Boolean,是的话则将Boolean转为Number再来比较
3.比较的一方有引用类型
a. 如果其中一方为Object,且另一方为String、Number或者Symbol,会将Object转换成字符串,再进行比较。
b. 两方都为引用类型,则判断它们是不是指向同一个对象。
课后习题
1. typeof 1/-0
2. true || false && false
3. "2" == 2?1:2
进阶题
1. 如何证明 - * / % 是先将二者隐式转换为 Number,而不是先隐式转换为 String?
2. !+[]
3. 如何只用 ! + [ ] 四个字符生成数字5
4. 如何只用 ! + [ ] 四个字符生成字符串 '55'
5. 如何只用 ! + [ ] 四个字符生成字符串 ---> 'res'
note: 进阶题为曾风靡一时的jsfuck混淆逻辑