JavaScript类型识别

来源:互联网 发布:淘宝双十一销量排行 编辑:程序博客网 时间:2024/04/30 09:04

JS是一个弱类型的语言,在声明变量的时候不需要指定变量的类型,在为变量赋值,传递实参给函数时也不需要进行类型检查。但有的时候类型检查却又是必要的。使用类型检查可是在JS中实现另一中意义下的函数重载,并提高安全性。这里先深入不讨论类型识别的意义,而这讨论类型识别的方法。

类型识别的方法有以下几种,typeof操作符,Object.prototype.toString()obj.constructorinstanceof

我们先看一看每个方法的用法,再来仔细讨论它们的区别,优缺点。

typeof:

typeof图片1
typeof图片2

从以上两张图来看,typeof可以识别基本类型值的类型,所有引用类型值的类型都会被识别为object,除了function,它会被识别为function,这里有一个值得注意的地方,typeof操作符,返回的字符串是小写的。后面我们会看到其它的方法,返回的字符串内容,首字母是大写的。
原因就在于,除了typeof方法,其它的方法返回的值基本都可以认为是构造器对象的名称。我后文再解释。这这里还要留意,null被识别为object。可以猜,在某一个阶段,function曾经被设计为单独的类型而不是object。

Object.prototype.toString().call(obj);

toString
我们来解释一下这一语句,首先,Function.prototype.call()函数设置function的this值,然后调用函数。
ecma1
上图是EcmaScript5标准对该函数的解释。非常容易理解,唯一不清楚的地方就是[[class]]属性。用两对中括号包围的属性是内部属性。我也没有看过ECMA标准,这里直接粘贴标准的解释。
ecma2

可见这个函数可以识别出所有‘内置对象‘(确切的说是,识别出内置对象创造的实例对象的类型,这个类型就是内置对象),内置对象并不是某种数据类型,它是引用类型object的值,但是内置对象中有比较特殊的构造器对象,它是一个用来创造对象的函数,所以它抽象了它所创造出来的对象的特点,按照面向对象的定义,它也可以认为是”数据类型”。至于Math这种对象因为是内置对象所以也可以被识别,它可以认为是单例的”数据类型”。构造器对象命名一般是Pascal格式,所以返回的字符串首字母会大写。当识别基本类型值时,基本类型值会转化为相应的包装对象并返回对应的构造器对象类型。

constructor:

通过原型中的constructor属性识别值的类型。
con
实例对象的prototype属性中有constructor属性,这个属性引用了构造函数对象。我们通常把构造函数的名字等同于数据类型的名称,利用正则表达式获取这个名称即可以确定值的类型(注意这个类型不是标准类型中的一种,或者说它们都是标准类型中的object)。我们很快注意到了,这个方法没有处理undefined和null但是可以处理自定义构造函数创造的实例对象。

instanceof

instanceof可以确认某个实例对象是否是某个构造器函数的实例。所以你不能把它直接作用在基本类型值上,其实前文中的constructor,toString也没法用在基本类型值上,只不过前面,内部将基本类型值包装成了一个实例对象。instanceof通过原型中的constructor确定,实例对象是否是构造器对象的实例。只要在原型链中存在,都返回true。这点和其它面向对象的语言一样。

到这里,你基本上应该对这几种方法都很清楚了,不需要我再做对比了。

0 0
原创粉丝点击