js语法学习之判断一个对象是否为数组

  1,真正的数组的判断方法

  javascript中最简单的声明数组方法为:

  var a = [];

  判断是否为数组的最直接的方法为:

  

复制代码 代码如下:

  a instanceof Array //true

  a .constructor == Array //true

  这里涉及到一个instanceof语法,instanceof是一个云算符,与"+-*/"一样,它的语法如下:

  result = obj intanceof class

  是用来判断一个对象是否是某个class的一个实例,运算结果返回true或者false。javascript中class的定义又是通过构造函数进行初始化的,所以instanceof语法的右操作符class一定是Function的实例,即class instanceof Function一定为true,而且如果使用instanceof时右操作符不是Function,就会抛出TypeError异常。所有对象都是Object的实例,所以任何对象instanceof Object都返回true。虽然我们说对象都是通过构造函数进行初始化的,但是instanceof却不是通过检查对象是否由该函数构造的,而是通过是否由构造函数的prototype继承来的,下面这个例子可以说明这个问题:

  

复制代码 代码如下:

  function Range(low, high) {

  this.low = low;

  this.high = high;

  }

  Range.prototype.constructor == Range; //true

  Range.prototype = {

  include: function(x){ return (x >= this.low && x <= this.high); },

  exclude: function(x){ return (x < this.low && x > this.high); }

  }

  var r = new Range(0, 100);

  r instanceof Range; //false

  r instanceof Object; //true

  Range.prototype.constructor == Objecct; //true

  这里虽然r是通过new Range构造的,但是r却并不是Range的实例,这就是问题所在,Range.prototype赋值语句覆盖了默认的构造函数,没对prototype赋值之前Range.prototype.constructor为Range,赋值之后变成了Object,这也好理解,因为

  

复制代码 代码如下:

  Range.prototype = {

  include: function(x){ return (x >= this.low && x <= this.high); },

  exclude: function(x){ return (x < this.low && x > this.high); }

  }

  其实等价于:

  

复制代码 代码如下:

  Range.prototype = new Object({

  include: function(x){ return (x >= this.low && x <= this.high); },

  exclude: function(x){ return (x < this.low && x > this.high); }

  });

  所以Range.prototype.constructor == Object,那么通过new Range创建出来的实例当然就是Object的一个实例了。

  看官方解释更直接些:

  The instanceof operator does not actually check whether r was initialized by the Range constructor. It checks whether it inherits from Range.prototype.

  javascript中还有一个函数typeof具有与instanceof类似的功能,但是它返回的是具体的基本数据类型:number,string,function,object,undefined,boolean,只有这六种,不在这六种范围内的都返回object,也就是说typeof([])返回的是object,而不是array。

  另一个涉及到的语法是constructor,constructor返回对象的构造函数:

  

复制代码 代码如下:

  var a = [];

  a.constructor; //Array

  构造函数是一个对象的初始化函数,采用new调用,如果对象是一个Array,那么其constructor应该就是Array,自己写的类就不一定了,因为可能会吧prototype中的constructor更改掉。

  2,伪数组的判断方法

  javascript中有一种伪数组,它可以使用类似于Array的遍历方法进行遍历,有length属性获取元素的长度,可以使用[]下标来获取指定的元素,这种对象我们称之为伪数组,JQuery中的对象就是典型的伪数组,如下图:

js语法学习之判断一个对象是否为数组

  所以判断是否是伪数组的关键就是判断是否有length属性,是否存在基本的数组操作函数splice,下面就是判断方法:

  

复制代码 代码如下:

  var is_array = function(value) {

  return value &&

  typeof value === 'object' &&

  typeof value.length === 'number' &&

  typeof value.splice === 'function' &&

  !(value.propertyIsEnumerable('length'));

  };

  这里propertyIsEnumerable就是用来判断length属性是否可列举,其实原生的String对象也是有类似Array的效果,但是我们不能把它当作Array对象,所以这里需要判断typeof value == "object",因为typeof一个String对象,返回的是string。