检测数组

instanceof

判断某一个对象是不是数组,对于一个网页或者一个全局作用域而言,使用instanceof操作符就能得到满意的结果:

if(value instanceof Array){//执行操作}

//instanceof实现
function instanceOf(left,right) {
    //获得类型的原型
    let prototype = right.prototype
    //获得对象的原型
    left = left.__proto__
    //判断对象的类型是否等于类型的原型
    while (true){
        if(left == null){
            return false
        }
        if(prototype === left){
            return true
        }
        left = left.__proto__
    }
}

instanceof操作符的问题在于,它假定只有一个全局执行环境。如果网页中包含多个框架(一个页面包含多个frame),那实际上就存在两个及以上的全局执行环境,从而存在两个以上不同版本的Array构造函数(Array是window的属性)。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有不同的构造函数。

Array.isArray()

为了解决这个问题,ES5新增了Array.isArray()方法。这个方法的目的是最终确定某个值到底是不是数组,而不管它在哪个全局执行环境中创建的。用法如下:

if(Array.isArray(value)){//对数组执行某些操作}

在任何值上调用Object原生的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串。每个类在内部都有一个[[Class]]属性,这个属性中就指定了上述字符串中的构造函数名。举例:

alert(Object.prototype.toString.call(value));
//“[object Array]”

由于原生数组的构造函数名与全局作用域无关,因此使用toSting()就能保证返回一致的值。利用这一点,可以创建如下函数:

function isArray(value){
    return Object.prototype.toString.call(value)=="[object Array]";
}

同样,也可以基于这个思路来测试某个值是不是原生函数或正则表达式。


日常输入输出
9 声望0 粉丝

愿望是成为优秀的前端工程师