判断是不是数组的几种方法— (js基础复习第1期)

1. 首先,typeof确定是不行的

对于一些基本类型,typeof是能够判断出数据类型,可是判断一些引用类型时候,不能具体到具体哪种类型
再来复习一下typeof的用法:javascript

// 基本类型
typeof 123;  //number
typeof "123"; //string
typeof true; //boolean
typeof undefined; //undefined
typeof null; //object
let s = Symbol;
typeof s; //symbol

// 引用类型
typeof [1,2,3]; //object
typeof {}; //object
typeof function(){}; //function
typeof  Array; //function  Array类型的构造函数
typeof Object; //function  Object类型的构造函数
typeof Symbol; //function  Symbol类型的构造函数
typeof Number; //function  Number类型的构造函数
typeof String; //function  String类型的构造函数
typeof Boolean; //function  Boolean类型的构造函数

2. 两种简单,可是不是十分准确的方法

var obj = [4,67,23];
obj instanceof Array; //return true 
obj.constructor == Array; // return true

为何不许确?java

2.1 首先来复习一下instanceof用法

判断一个实例是否属于某种类型web

function Foo(name) {
    this.name = name;
}
var f = new Foo('zhangsan');
console.log(f instanceof Foo); //true
console.log(f instanceof Object); //true

判断一个实例是否属于它的父类型segmentfault

function Person() {};
function Student() {};
var p = new Person();
Student.prototype = p;
var s = new Student();
console.log(s instanceof Student); //true
console.log(s instanceof Person); //true

记忆:
A instanceof C   等价于  A 是不是 C子类,或者后代?

2.2 instanceof 判断逻辑?

判断逻辑翻译成js代码以下:数组

_instanceof(f, Foo);  

function _instanceof(L, R) {
    var R = o.prototype;
    var L = L.__proto__;
    while( true) {
        if(L == null) {
            return false;
        }
        if(L == R) {
            return true;
        }
        L = L.__proto__;
    }
}

2.3 instanceof 不许确的缘由?

代码以下:浏览器

var iframe = document.createElement('iframe');
    document.body.appendChild(iframe);

    var arr = [1,2,3];
    xArray = window.frames[0].Array;  //iframe中的构造函数
    var arrx = new xArray(4,5,6);

    console.log(arrx instanceof Array);  //false
    console.log(arrx.constructor == Array);// false

    console.log(Array.prototype == xArray.prototype); //false
    console.log(arr instanceof xArray); //false

    console.log(arrx.constructor === Array);// false
    console.log(arr.constructor === Array);// true
    console.log(arrx.constructor === xArray);// true
    console.log(Array.isArray(arrx));  //true

解释:红宝书,p88 app

instanceof操做符的问题在于,它假定只有一个全局环境。若是网页中包含多个框架,那实际上就存在两个以上不一样的全局执行环境,从而存在两个以上不一样版本的Array构造函数。
若是你从一个框架向另外一个框架传入一个数组,那么传入的数组与在第二个框架中原生建立的数组分别具备各自不一样的构造函数。框架

2.4 constructor 不许确的缘由?

由于constructor能够被重写,因此不能确保必定是数组
example:函数

var str = 'abc';
    str.constructor = Array;
    str.constructor === Array // return true

而很明显str不是数组。
并且constructor和instanceof存在一样问题,不一样执行环境下,constructor判断不正确问题。this

3. isArray()

最终肯定某个值究竟是不是数组,而无论它是在哪一个全局执行环境中建立的,这个方法的用法以下。

if(Array.isArray(value)){
    return true;
}

4. Object.prototype.toString

若是在还没有实现isArray方法的浏览器中准确监测数组,咱们须要用到Object.prototype.toString方法来判断,每个继承自Object的对象都拥有toString的方法。

if(!Array.isArray){
    Array.isArray = function(arg){
        return Object.prototype.toString.call(arg)==='[object Array]'
    }

}

本身能够封装一个获取变量类型的函数

function getType(obj) {
    return Object.prototype.toString.call(obj).slice(8,-1);
}

var a = [1,2,3];
console.log(getType(a)); //Array 

var b = function(){};
console.log(getType(b)); //Function

5. 参考文章

JavaScript instanceof 运算符深刻剖析
javascript 判断变量是不是数组(Array)

相关文章
相关标签/搜索