经常有人会在JavaScript里写如下的方法:
1 2 3 4 5 6 7 8 9 10 | function checkType() { var s1 = 123; var s2 = "OK" ; if (s1 instanceof Number) { alert( "s1 is a number." ); } if (s2 instanceof String) { alert( "s2 is a String." ); } } |
问题在哪里呢?
首先我们要理解,JS里,var本身是一个泛型,它并不是Number,也不是String,更不是其他的类。
其次要从instanceof方法来理解:
第一:
instanceof 表示对象是否是特定类的一个实例。
注意特定类的实例,也就是说instanceof反馈的是对象的构造的信息。
语法为:result = object instanceof class
例如:
1 2 3 | function Test() {} var test = new Test(); alert(test instanceof Test); |
第二:
String 类型的声明。
使用 var str = new String("String");声明定义的是一个String类型的对象。str指向该对象的一个引用
使用 var str1 = "String";声明定义将str指向字符串“String”,
str指向一个实例,str1指向一个字符串。
以上声明定义的规则,同java类似。
访问str时,JavaScript引擎会“自动拆装包”得到str的对象实例所表示的值“String”。所谓“自动拆装包”即运行期时,基础数据类型 转换成基础类型构造的对象实例以及将基础类型构造的对象实例转换成基础数据类型。如“new Number”、new Boolean("true")、new String等。
因此s2只有自己的基本类型而没有所谓的实例构造类型
即,我们定义了var s1 = 123, 它的类型并不是Number,而是var。
只有我们把123实例化为Number的时候,它的类型在instanceof里才是Number。
其他的自定义类一样。
另外一个方法typeof
JavaScript中instanceof和typeof都能用来判断一个变量是否为空或是什么类型的变量。
typeof用以获取一个变量的类型,typeof一般只能返回如下六种结果:
number, boolean, string, function, object, undefined。
我们可以使用typeof来获取一个变量是否存在,如
1 | if ( typeof a!= "undefined" ){} |
而不要去使用if(a),因为如果a不存在(未声明)则会出错,
对于Array,Null等特殊对象使用typeof一律返回object,这正是typeof的局限性。
如果我们希望获取一个对象是否是数组,或判断某个变量是否是某个对象的实例则要选择使用instanceof。
instanceof用于判断一个变量是否某个对象的实例,如
1 2 | var a= new Array(); alert(a instanceof Array); |
会返回true,
同时
1 | alert(a instanceof Object) |
也会返回true;
这是因为Array是object的子类。
再如:
1 2 3 | function test(){}; var a= new test(); alert(a instanceof test) |
会返回true。
谈到instanceof我们要多插入一个问题,就是function的arguments,
我们大家也许都认为arguments是一个Array,
但如果使用instaceof去测试会发现arguments不是一个Array对象,尽管看起来很像。
另外:
测试
1 2 3 4 5 6 | var a = new Array(); if (a instanceof Object) { alert( 'Y' ); } else { alert( 'N' ); } |
得到'Y'
但
1 2 3 4 5 | if (window instanceof Object) { alert( 'Y' ); } else { alert( 'N' ); } |
得到'N'
所以,这里的instanceof测试的object是指js语法中的object,不是指dom模型对象。
使用typeof会有些区别
1 | alert( typeof (window) |
会得到 object