JavaScript变量类型检测问题

String类型变量检测(字符串)

String类型变量生成方式

  1. var str1 = "hello world";
  2. var str2 = new String("hello world");

String类型变量检测

function IsString(str){
    return (typeof str == "string" || str.constructor == String);
}

那么这里为什么需要进行两种判断呢?仅仅一种难道不够嘛,答案确实是不够的。详细看下面的示例,你就会明白了。

一些示例:

1.第一种方式生成字符串变量

var str1 = "hello world";
alert(typeof str1); //result : "string"
alert(str1.constructor); //result : String的引用 -> function String(){[native code]}
alert(str1 instanceof String); //result : false

2.第二种方式生成字符串变量

var str2 = new String("hello world");
alert(typeof str2); //result : "Object"
alert(str2.constructor); //result : String的引用 -> function String(){[native code]}
alert(str2 instanceof String); //result : true
结果不同点
生成字符串变量的方式 typeof constructor instanceof
"hello world"; "string" String的引用 false
new String("hello world"); Object String的引用 true

Array类型变量检测(数组)

Array类型变量生成方式

类比于字符串变量生成方式,数组变量生成方式也有两种:

  1. var arr1 = [1,2,3];
  2. var arr2 = new Array([1,2,3]);

Array类型变量检测

function IsArray(str){
    return (str.constructor == Array);
}
结果完全相同
生成字符串变量的方式 typeof constructor instanceof
[1,2,3]; Object Array的引用 true
new Array([1,2,3]); Object Array的引用 true

通用比较靠谱的方法

由于对于StringArray来说,各种方法得到的结果不太相同,所以用这些方法比较麻烦。下面是一种比较通用且靠谱的方法。

toString()

Object.prototype.toString.call(param)将会返回param的类型,返回结果如下:[object type]
toString被调用的时候,会执行如下步骤:(ES5.1)

  1. 如果this的值为undefined,那么返回"[object Undefined]";
  2. 如果this的值为null,那么返回"[object Null]";
  3. O成为调用ToObject(this)的结果;
  4. class成为O的内部属性[[Class]]的值;
  5. 返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.

关于[[Class]]:

所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.[[Class]]内部属性是引擎内部用来判断一个对象属于哪种类型的值的.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2).

注意:

Object.prototype.toString.call(param)返回的"[object class]"中class首字母是大写,像JSON这种甚至都是大写,所以,大家判断的时候可以都转换成小写,以防出错,Object.prototype.toString.call(param).toLowerCase()即可。