javascript判断是否为数组的方法

来源:互联网 发布:淘宝联盟鹊桥手机登录 编辑:程序博客网 时间:2024/05/22 22:37

javascript判断是否为数组的方法

很多时候我们需要对JavaScript中数据类型( Function、String、Number、Undefined、Boolean和Object)做判断。在JavaScript中提供了typeof操作符可以对这些常用的数据类型做判断。但要使用typeof来判断数据是不是一个数组,就不起作用了

     console.log(typeof function () {return;}); // function     console.log(typeof "a"); // string     console.log(typeof 123); // number     console.log(typeof a); //undefined     console.log(typeof true); // boolean     console.log(typeof NaN); // number     console.log(typeof !NaN); //boolean     console.log(typeof {name:"leo",age: "37"}); // object     console.log(typeof ["leo","37"]); // object     console.log(typeof null); // object

es5的isArray()函数

var arr = [1,2,3,45];function isArray(obj){    return Array.isArray(obj);    }alert(isArray(arr));

ECMAScript 5 还有着非常大的兼容性,所以我们并不能完美的使用原生判断,当使用ie6/7/8的时候就会出现问题。

construct和instanceof

  • constructor属性返回对创建此对象的函数的引用,使用此属性可以检测数组类型
  • 除了使用constructor自身属性之外,还可以使用instanceof
    instanceof用来判断某个构造函数的prototype是否存在于被检测对象的原型链里。也就是判断前面的对象是否是后者对象的类或者实例。
var arr = [1,2,3,45];console.log(arr.constructor === Array);console.log(arr instanceof Array);
  • 缺点:需要注意的是,当在不同的window或iframe里构造的数组时会失败。这是因为每一个iframe都有它自己的执行环境,彼此之间并不共享原型链,所以此时的判断一个对象是否为数组就会失败。此时我们有一个更好的方式去判断一个对象是否为数组。
    当你在多个frame中回来跳的时候,这两种方法就惨了。由于每一个frame都有自己的一套执行环境,跨frame实例化的对象彼此并不共享原型链,通过instanceof操作符和constructor属性检测的方法自然会失败。

Object.prototype.toString

 var is_array = function(obj){    return Object.prototype.toString.call(obj) === '[object Array]';};alert(is_array(arr));

使用Object.prototype.toString方法来检测对象类型。toString将返回[object type] type为对象类型。下面是对象检测显示的结果。

     var toString = Object.prototype.toString;      console.log(toString.call(dd));//[object Function]      console.log(toString.call(new Object));//[object Object]      console.log(toString.call(new Array));//[object Array]      console.log(toString.call(new Date));//[object Date]      console.log(toString.call(new String));//[object String]      console.log(toString.call(Math));//[object Math]      console.log(toString.call(undefined));//[object Undefined]      console.log(toString.call(null));//[object Null]

因此我们可以利用对象的Object.prototype.toString方法检测对象是否为数组。在frame下也通过。
- #### 最佳检测 -Array和Object.prototype.toString结合
最佳检测方法就是,不管原生isArray是否可用,都回归到object.prototype.toString的检测上。
- Object.prototype.toString的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于”[object Array]”的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这 个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。
- call改变toString的this引用为待检测的对象,返回此对象的字符串表示,然后对比此字符串是否是[object Array],以判断其是否是Array的实例。为什么不直接o.toString()?嗯,虽然Array继承自Object,也会有toString方法,但是这个方法有可能会被改写而达不到我们的要求,而Object.prototype则是老虎的屁股,很少有人敢去碰它的,所以能一定程度保证其“纯洁性”:)

JavaScript 标准文档中定义: [[Class]] 的值只可能是下面字符串中的一个:

Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String
<script> var isArray = function () {            if (Array.isArray) {                return Array.isArray;            }            var objectToStringFn = Object.prototype.toString,                 arrayToStringResult = objectToStringFn.call([]);            return function (subject) {                        return objectToStringFn.call(subject) === arrayToStringResult;            };  }();  alert(isArray(arr));// true  <script>