今天做题的时候遇到两个坑,虽然很简答,但是mark一下 :
1. for…in 遍历数组的“下标”
for…in 语句遍历的是一个对象的key,在遍历数组的时候尤其具有迷惑性:
const arr = [1,2,3]
for(let i in arr) {
console.log(typeof i) // string
}
对,没看错,这遍历出来的不是0,1,2 这样的number
类型的下标,而是string,为什么呢?
原因是,在JavaScript
中,Array
属于Object
的子类,而Object
是一种类似于哈希表的数据结构,以字符串作为key
,value
可以是任何数据类型。(顺带一提,JS
中的Map
是更灵活的一种哈希表,key
不仅可以是字符串,还可以是任意数据类型)。
因此,Array
的key
也是string
类型,它和普通Object
的区别是:key
是递增的转成字符串的数字,并且实例可以访问Array.prototype
上的方法。
比如'0'
、'1'
、'2'
… 之所以我们可以通过arr[1]
这样的方式以数字下标的形式随机访问数组,我个人理解是解释器自动做了类型转换。
(顺便一提,key
是递增的转成字符串的数字,但是原型链上没有Array.prototype
的对象是伪数组。)
这样就能解释为什么for … in 访问到的是字符串了,因为它访问的是对象的key
,而key
就是string
类型的。
2. for…in
在JS里,下列表达式的结果竟然是true !
console.log(0 < 100 < 4) //true
在C++中,也是同样的情况:
cout << (0 < 100 < 4) << endl; //1
这是因为,首先0<100会执行,结果是true,然后true和4比较,true被自动类型转化成1,1<4为true,所以最终答案为真。
而同样的语句在python中,是这样的:
print(0 < 100 < 4) // False
这个符合正常的不等式逻辑。
如果写成下面这个形式,那和JS,C++的情况就一样了:
print((0 < 100) < 4) // True