判断是否为数组
1 Array.isArray()
Array.isArray() 是ES5新增的方法,用于确定传递的值是否是一个数组,如果是数组,则返回 true,否则返回 false
//true
console.log(Array.isArray([])) //true
console.log(Array.isArray(new Array())) //true
console.log(Array.isArray(new Array('a', 'b'))) //true
console.log(Array.isArray(Array.prototype))//true ⭐
//false
console.log(Array.isArray())//false
console.log(Array.isArray(null))//false
console.log(Array.isArray(undefined))//false
console.log(Array.isArray(Object))//false
console.log(Array.isArray(Function))//false
2 constructor
const arr = []
console.log(arr.constructor === Array); //true
注意 constructor有被修改的风险
const arr = []
arr.constructor = Object
console.log(arr.constructor === Array) //false
3 instanceof
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
//举例
function A() { }
function B() { }
const a = new A()
const b = new B()
console.log(a instanceof A); //true
console.log(b instanceof A); //false
console.log(a instanceof Object); //true
console.log(A.prototype instanceof Object); //true
我们可以用instanceof判断是否为数组
let arr = []
console.log(arr instanceof Array); //true
注意
- 构造函数的 prototype 和 实例的原型链都有可能会改变,所以判断出的结果不一定一成不变。
- 在有 iframe 的页面脚本中使用 instanceof,可能会得到错误的结果,因为 iframe 拥有独立的全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。
4 Object.prototype.toString.call()
说明每一个继承自Object的对象都拥有toString的方法
作用这个方法可以精确的判断变量类型,会返回一个字符串数组,我们判断Object.prototype.toString.call(arr)是否等于字符串'[object Array]',判断arr是否为数组
问题一
toString方法是将数据以字符串形式输出,数组也有toString方法,为什么用Object原型上的toString?
数组中的toString方法是被改写过的,不能用,项判断各数据类型,只能通过顶端的Object原型来实现
问题二
为什么用call()不能直接toString?
因为我们我们要判断数组的数据类型,而不是Object的类型,通过call()改变this指向
//判断是否为数组
let arr = []
console.log(Object.prototype.toString.call(arr) === '[object Array]'); //true
//判断其他数据类型
//判断简单数据类型
console.log(Object.prototype.toString.call(null) === '[object Null]') //true
console.log(Object.prototype.toString.call(undefined) === '[object Undefined]')//true
console.log(Object.prototype.toString.call('abc') === '[object String]')//true
console.log(Object.prototype.toString.call(123) === '[object Number]') //true
console.log(Object.prototype.toString.call(true) === '[object Boolean]')//true
//复杂数据类型
//函数类型
function fn() { }
console.log(Object.prototype.toString.call(fn) === '[object Function]') //true
//日期类型
console.log(Object.prototype.toString.call(new Date()) === '[object Date]')//true
//正则
console.log(Object.prototype.toString.call(/\|/g) === '[object RegExp]') //true