数据类型
JavaScript的数据类型有七种:
Boolean:布尔值,true 和 false 两个特定值
Null:表示无值,即此处的值就是“无”的状态
Undefined: 表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
Number:整数和小数
String:字符组成的文本
Symbol (这个是ES6新定义的数据类型)
Object:各种值组成的集合
其中Boolean、Null、Undefined、Number、String和Symbol称为原始类型,即它们是最基本的数据类型,不能再细分。而 Object 称为合成类型,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。其中对象又可分成三个子类型:
侠义的对象(object)、数组(array)、函数(function)
数据类型检测
在JavaScript中有四种方法,可以确定一个值到底是什么类型:
typeof运算符
instanceof运算符
constructor运算符
Object.prototype.toString方法
typeof运算符
instanceof运算符
instanceof 运算符用于检查某个对象的原型链是否包含某个构造函数的 prototype 属性。
使用instanceof来判断A是否为B的实例对,表达式为A instanceof B,如果A是B的实例则返回true,否则返回false。
在JavaScript原型继承结构里面,用[[Prototype]]表示对象隐式的原型,在JavaScript中用proto表示,并且在Firefox和Chrome浏览器中是可以访问得到这个属性的,但是IE下不行。所有JavaScript对象都有proto属性,但只有Object.prototype.proto为null,前提是没有在Firefox或者Chrome下修改过这个属性。这个属性指向它的原型对象。至于显示的原型,在JavaScript里用 prototype 属性表示。
instanceof 只能用来判断两个对象是否属于原型链的关系, 而不能获取对象的具体类型。
constructor运算符
当一个函数foo被定义时,JavaScript会给foo函数添加prototype原型,然后再在prototype上添加一个constructor属性,并让其指向foo的引用,如下:
当执行var bar = new foo()时,foo被当成了构造函数,bar是foo的实例对象,此时foo原型上的constructor传递到了bar上,因此bar.constructor == foo(返回的是一个true)。
可以看出,JavaScript在函数foo的原型上定义了constructor,当foo被当作构造函数用来创建对象时,创建的新对象就被标记为foo类型,使得新对象有名有姓,可以追溯。同理,JavaScript中的数据类型也遵守这个规则:
在JavaScript中null和undefined是比较特殊的数据类型,也是无效的对象,因此是不会有constructor存在的,这两种类型的数据需要通过typeof来判断。另外,JavaScript对象的constructor是不稳定的,这个主要体现在自定义对象上,当开发者重写prototype后,原有的constructor会丢失,constructor会默认为Object。
为什么变成了Object?
prototype被重新赋值的是一个{},{}是new Object()的字面量,因此new Object()会将Object原型上的constructor传递给{},也就是Object本身。因此,为了规范,在重写对象原型时一般都需要重新给constructor赋值,以保证实例对象的类型不被改写
Object.prototype.toString
toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx是具体的数据类型,其中包括:String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,… 基本上所有对象的类型都可以通过这个方法获取到。
需要注意的是,必须通过Object.prototype.toString.call来获取,而不能直接 new Date().toString()。
强制转化
强制转换主要是指使用Number()、String()和Boolean()三个构造函数,手动将各种类型的值,转换成number、string和boolean。
使用Number()函数,可以将任意类型的值转化成数值
使用String()函数,可以将任意类型的值转换成字符串
使用Boolean()函数,可以将任意类型的变量转换为布尔值
Boolean()的转换规则相对简单:除了以下六个值的转换结果为false,其他的值全部为true。
注意:所有对象,包括空对象的转换结果都是true,甚至连false对应的布尔对象new Boolean(false)也是true: