1、不要使用Object.prototype.toString.call()
正常情况下:
const arr = [1,2,3,4,5] const obj = {} console.log(Object.prototype.toString.call(arr))//[Object,Array] console.log(Object.prototype.toString.call(obj))//[Object,Object]
过去我们能够通过判断Object.prototype.toString.call(arr)第二个单词是否为Array来判断是否为数组,
但是时代变了,现在不行了。因为现在可以使用一个知名符号 toStringTag 改变生成的数组
例如:
const arr = [1,2,3,4,5] const obj = { [Symbol.toStringTag]:'Array', } console.log(Object.prototype.toString.call(arr))//[Object,Array] console.log(Object.prototype.toString.call(obj))//[Object,Array]
看到了吗?对象用这个方法,也可以把第二个单子变成Array。
虽然概率很小,但是不得不防。还是那句话你可以不用,但是你不能知道!!!
2、不要使用instance of
原理是通过判断一个对象上有没有Array的原型
正常情况下:
const arr = [1,2,3,4] const obj = {} console.log(arr instanceof Array) //true console.log(obj instanceof Array) //false
说完正常情况下,就说一说不正常的情况下
- 通过Object.setPrototypeOf 将对象的原型改变为数组的原型
const arr = [1,2,3,4] const obj = {} Object.setPrototypeOf(obj,Array.prototype) console.log(arr instanceof Array) //true console.log(obj instanceof Array) //true
将对象也判断成数组了 ,哒咩
-
在页面环境中有iframe
由于iframe会生成一套独立的document和独立的window,但是Array是window一个全局属性,这就造成了一个非常有意思的现象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <iframe src="" frameborder="0"></iframe> </body> <script> const Array1 = window.Array const iframe = document.querySelector('iframe') const Array2 = iframe.contentWindow.Array const arr = new Array2() console.log(arr instanceof Array) //false </script> </html>
虽然我觉得出现这种情况的概率很小,但是还是那句话你可以不用,但是你不能知道!!!
3、唯一解:Array.isArray
const arr = [1,2,3,4,5] //上述两种情况均可用Array.isArray判断 Array.isArray(arr) //true