背景
最近看到一些关于 javascript
类型判断的问题,就突然发现好像自己也没有自己去总结过这些知识点,都是零零散散的,看到一个记一个,忘记了就搜索引擎搜索一下。今天就做一个总结,关于 javascript
中的一些看着挺奇怪的一些类型。面试的时候可能会被问到哟!
1. NaN
第一个就 NaN
非他莫属,绝对最“奇葩”的一个类型,唯一一个“我不等于我自己”的类型。
- 申明:
Number.NaN
或者NaN
- 判断
NaN
的判断有点奇怪,因为他的typeof
结果是'number'
,所以在日常开发中,判断类型的时候一定要非常非常小心,不然一不小心页面上可能就会显示一个NaN
哟,不管是==
还是===
都是不相等的,就理解成调用Number.NaN
生成的数据是新的就好了
isNaN
和Number.isNaN
奇怪的点还有两个不同的判断方法,
isNaN
是会做类型转换的,比如isNaN('hello world');
的结果是true
, 他会把"hello world"
转成number
类型,然后再判断是不是NaN
,但是Number.isNaN
就不会啦,他只会判断参数是不是NaN
类型,并不会做类型转换,所以isNaN('hello world')
的结果是false
- 总结
虽然我们很少在写代码的时候,直接去使用
NaN
这个类型,但是在做数字类型的处理的时候,他可能会出现(比如:Math.sqrt(-1)
)。所以。处理数字类型的时候,还是要小心一下NaN
情况的出现,判断是否是NaN
的类型的时候,也要注意isNaN
和Number.isNaN
的区别。避免让页面出现预期意外的情况
2. Symbol
这个也是我在日常开发中用的比较少(机会没有用过)的类型,但是有些面试官就喜欢问,我只在 react
的源码中见到过,本来也想尝试在项目开发中使用,但是也没找到很合适的机会。但是知识点还是要掌握的嘛
- 申明:他作为构造函数并不完整,所以不支持
new
的语法
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');
- 判断
Symbol
的判断是可以通过简单的typeof
来进行判断的。typeof symbol1
的结果是'symbol'
,但是如果用两个symbol
来判断是不可以的,类似这种操作Symbol('foo') === Symbol('foo')
结果就是false
- 奇怪的操作
他和我们普通对象不一样,他在迭代中不可枚举,如果有下面这种操作,可就要小心了,用Symbol
做为key
的数据是不会被转到结果中去的,for ... in
也是不能拿到相对应的键的,但是可以通过Object.getOwnPropertySymbols()
来获取。const obj = { [Symbol("foo")]: "foo", name: "george" } const res = JSON.stringify(obj) // '{"name":"george"}' // 返回的是一个数组 Object.getOwnPropertySymbols(obj) // [Symbol(foo)] // toString操作 const symbolData = Symbol("bar"); Symbol(foo).toString() // 'Symbol(foo)'
- 总结
Symbol 的操作真的太多了,不过用的真的很少,我在公司好几个项目都没找到有人用它,如果后面有知道实际使用的场景再来更新,资料参考 MDN 官网
3. 数组相加
这个可能只能在 javascript
中才能出现的现象了
const a = [1, 2, 3, 4, 5]
const b = [6, 7, 8]
const res = a + b
// 结果就是:'1,2,3,4,56,7,8',会先做类型转换,转换成字符串再相加
const ret = [] + []
console.log(ret) // ''
// 最让我觉得离谱的是下面这个
[] + {} // '[object Object]'
{} + [] // 0
因为
[].toString()
是''
,但{}.toSting()
是'[object Object]'
,所以[] + {} === '[object Object]'
很合理,但是{} + []
为啥就是0
了呢?
其实是因为{}
他不止代表这一个空对象,他还代表着一个代码块,{}
在开头的时候编译器会以为这是一个代码块,里面啥也没有,然后就执行+[]
,也就把[]
转成number
类型了(相当于Number([])
),所以就是0
了。我在一些面试的笔试题也见过这种题,当时我也是大为震撼,完全懵逼。希望你如果下次遇到的时候,能从容作答。
4. 最小值(Number.MIN_VALUE
)比 0 大
Number.MIN_VALUE > 0
这个第一感觉也是很反人类的,但是 Number.MIN_VALUE
实际上表示可以用 JavaScript
中的浮点数表示的最小的正数,而不是最小的负数。如果想要创建一个非常小(或者非常大的数字)的变量可以用全局变量 -Infinity
(或 Infinity
),typeof Infinity
的类型是 number
5. 除以0不会报错
如果你跟后端的小伙伴说 javascript
中一个数除以 0 不会报错,他肯定会”瞳孔地震“,不止不会报错,还有一个奇怪的现象,我觉得这个在开发中可能会遇到,我们总是拿后端提供的数据进行操作嘛,然而 Number(null)
又是0,所以就难免会遇到除以 0 的情况
const res = 0 / 0 // res 是 NaN
const res2 = 1 / 0 // res2 是 Infinity
用 javascript
做数据的运算真的是处处充满惊喜,我之前做财务系统的时候,都是数据操作,后端总觉得提供了数据,我前端自己操作一下就行了,然后我就踩了各种坑,兄弟们如果要用 javascript
进行数据操作的话,真的要特别特别谨慎,这些基础知识一定要搞清楚,要不然,你的 bug
表真的会满满的
6. 数字 toString
不知道大家有没有写过这样的代码,
12321.toString()
如果尝试过这样的小伙伴,肯定知道这是会报错的。Uncaught SyntaxError: Invalid or unexpected token
直接就语法错误,那是不是说明 Number
类型的不可以使用 toString()
方法呢?那肯定不是的呀?你如果这种方式写是没有问题?那是为啥呢?
const num = 123
num.toString()
其实是因为在
javascript
中,数字后面加个.
还是一个合法的数字,比如我们可以这样写1. + 2.
,看起来很奇怪的,但是编译器能正常编译,所以如果我们想要使用数字去toString
的时候,需要在数字后面加一个空格,是不是很神奇?
// 这样的代码也是可以正常运行的
123.123 .toString()
虽然是个知识点,但是实际业务开发上应该也没人会这样写吧