美文网首页
判断是否为数组类型的4种方法

判断是否为数组类型的4种方法

作者: 悄敲 | 来源:发表于2019-03-06 21:26 被阅读0次

1. Object.prototype.toString.call()

该方法可以很好地区分各种类型,甚至是 null 和 undefined , 除了自定义对象类型(这个可用instanceof区分)。

console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/\d/));//[object RegExp]
function Person(){};
console.log(Object.prototype.toString.call(new Person));//[object Object]

那为什么直接用obj.toString()就不行呢?(obj为要判断其类型的对象)
Answer:因为 toString 为Object的原型方法,而Array、function等具体类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链相关知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其obj所属的类型。
验证:将数组的toString方法删除,看看会是什么结果.

    const arr=['hello','ki'];

    console.log(Array.prototype.hasOwnProperty('toString')); // true
    console.log(arr.toString()); // "hello,ki"

    delete Array.prototype.toString; //从Array.prototype对象上删除toString属性
    console.log(Array.prototype.hasOwnProperty('toString')); // false

    console.log(arr.toString()); // [object Array]
    console.log(Object.prototype.toString.call(arr)); // [object Array]

如上段代码所示,删除了Array原型上的 toString 方法后,再使用arr.toString()时,不再屏蔽Object原型对象上的toString方法,因此,返回了和Object.prototype.toString.call(arr)相同的结果。一图胜千言,还没明白的请看下图。(这里是为了验证,才从Array.prototype对象上删除toString属性,一般并不建议修改Array等内置对象)


涉及原型链的toString方法.png

Note: 该方法多用于判断内置对象,即非自定义对象类型。

2. instanceof : 通过判断对象的原型链中是不是能找到类型的 prototype。
例如使用 instanceof判断一个对象是否为数组,instanceof 会判断这个对象的原型链上是否会找到对应的 Array 的原型,找到返回 true,否则返回 false。

    let Person=function(){};
    let p=new Person();
    console.log(1 instanceof Number);  // false
    console.log('string' instanceof String); // false
    console.log(new Boolean(false) instanceof Boolean); // true
    console.log(p instanceof Person); // true

但 instanceof 只能用来判断对象类型(很适合判断自定义对象类型),原始类型不可以。并且由于所有对象都继承自Object,所以任意对象 instanceof Object 都是 true。

3. Array.isArray():用来判断对象是否为数组(ES5新增的方法).当检测Array实例时,Array.isArray 优于 instanceof ,因为 Array.isArray 可以检测出 iframes.

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

// Correctly checking for Array
Array.isArray(arr);  // true
Object.prototype.toString.call(arr); // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // false

4. constructor:和instanceof原理差不多。需要事先知道待判断的对象大概属于何种类型,所以该方法更准确地说,是用来验证的。如果我们事先根本不知道一个对象实例的出处,那就不好使了。

    let arr=[1,2,4];
    alert(arr.constructor===Array); // true

总结:各个方法之间存在一定的性能差异,但网上说法并不统一,可能与浏览器也相关。另外文中的解释部分需要原型链的知识基础。

相关文章

网友评论

      本文标题:判断是否为数组类型的4种方法

      本文链接:https://www.haomeiwen.com/subject/ierxpqtx.html