本文深入解析JavaScript的六种基本数据类型,重点剖析typeof运算符的特殊行为、null与undefined的判定差异、Boolean在条件语句中的隐式转换,以及Number和String类型的转换规则与性能考量。通过具体代码示例,揭示浮点运算精度、NaN判断机制及字符串不可变性等关键细节,帮助开发者避免常见类型错误。
JavaScript六种数据类型概览
JavaScript中主要包含六种数据类型:String(字符串)、Null(空值)、Number(数值)、Boolean(布尔值)、Object(对象)以及未提及但存在的Undefined(未定义)。
typeof运算符的特殊行为
1、typeof运算符的注意事项
讨论数据类型时,必然涉及操作符typeof。使用时需留意以下关键点:
首先,typeof属于操作符而非函数。尽管日常开发中常看到typeof()这种调用形式来获取对象类型,但这只是语法糖,本质仍是操作符。
其次,typeof对null的返回结果是object,这源于历史设计中null被视为空的对象引用;而对函数执行typeof则返回function。
代码如下:
alert(typeof null); //返回 object
function demo(){
alert('demo');
}
alert(typeof demo); //返回 function
变量初始值设置建议
2、为各类数据类型的变量设置初始值
特别注意,若Object类型的对象变量在初始化时暂不确定赋值内容,建议不要使用var demo={};更推荐将其初始值设为null。
代码如下:
var d2=null;
d2={'key':"shit"};
var d3='';//字符串 默认
var d4=0; //Number 类型 初始值设置为0
var d5=null; //对object 类型设置初始默认值
null与undefined的辨析
3、undefined与null的区别及注意事项
第一,若使用“==”进行比较,两者相等,因为比较的是值。
第二,区分二者有两种方法(核心在于比较它们的数据类型):
1)使用typeof将它们区分开
2)使用全等“===”:比较的是值和数据类型,只有当值和类型完全相同时才返回true。
代码如下:
alert(undefined == null); //true
alert(typeof undefined == typeof null); //false
alert(undefined === null); //true
Boolean类型转换规则
4、Boolean类型的注意事项
第一,true与1在“==”比较下相同,false与0在“==”比较下也相同。这是因为JS内部实现了数据类型转换,将true转换为1,false转换为0。JS内部存在大量自动类型转换机制,这一点需格外注意,后续还会涉及更多此类情况。但若使用“===”比较,则不相等,因为它们的类型不同。
第二,可通过Boolean()方法进行显式类型转换。需掌握各种数据类型在何种情况下转换为true,何种情况下转换为false。
1)String类型:只要不是空字符串,都会转换为true。
2)Number类型:只要不是0,即使是负数,也会转换为true。
3)Object类型:只要不是null,都会转换为true。
4)Undefined类型:均转换为false。
此处不再演示,读者可自行动手验证。
3、(***)if()语句的()内部实际上调用了Boolean函数进行判断。
Number类型运算与转换陷阱
5、Number类型的注意事项
第一,float类型(浮点数)无法进行精准运算。
代码如下:
alert(0.1+0.2);//返回 0.300000000000000004
第二,支持科学计数法运算。
第三,NaN(Not a Number,非数字)。
1)var d=0/0; 注意:在JS中不会报错,而是返回NaN。
2)可通过Number.NaN来获取NaN值。
3)NaN与任何对象进行运算,结果都会返回NaN。
4)使用isNaN()判断是否为NaN。
代码如下:
alert(isNaN(NaN));//true
alert(isNaN(12));//false
alert(isNaN('123'));//false:因为 字符串类型 的数字 可以自动转换成 数字
alert(isNaN('lew'));//true
alert(isNaN(false));//(*)false:因为 bool 值 可以转换成数字,true变1,,false 变 0
5)isNaN()的内部执行原理:同样适用于对象。实现原理:首先调用对象的valueOf()方法,如果能转换成数字就直接做判断;如果不能,再调用toString()方法,然后测试返回值。
valueOf()内部调用了toObject()方法,两个方法的内部执行原理:如下图:

代码如下:
var box={
//重写 box 对象的 toString() 方法
toString:function(){
return '123';
}
};
alert(isNaN(box));//false
alert(box);//123 alert()内部也是 先调用了 对象的 valueOf() 然后调用 toString()方法
6)将其他数据类型转换成Number类型
包含三个函数:Number():可针对所有数据类型进行转换;parseInt()和parseFloat():仅针对字符串进行转换。
代码如下:
alert(Number('123'));//123
alert(Number('0234'));//234
alert(Number(true));//1
alert(Number(null));//(**)0
//除了 上面的 其他的都是 返回 NaN
alert(Number(undefined))//NaN
Number()内部实现原理:同isNaN(),也是先调用valueOf()然后调用toString()。因此,其性能相对较差。所以,只要确定要被转型的对象是字符串,建议调用parseInt()或parseFloat(),因为它们内部无需进行类型判断。
parseInt()和parseFloat()调用注意事项:从第一个为数字的字符开始,一直到第一个非数字字符的前一个数字,这部分字符串会被转换成数字。
代码如下:
alert(parseInt('123leb'));//123
alert(parseInt('123leb345'));//123
alert(parseInt('len234'));//NaN
当parseInt()里面的参数是float类型的,那么只取得数字的整数部分。
代码如下:
alert(parseInt(56.12));//56
String类型的不变性与转换
6、String类型
1)(*重要*)在ECMAScript中,字符串具有不变性:字符串创建之后就不会再改变。
若要改变一个已被赋值的字符串变量,首先需要销毁变量中的字符串,然后再用一个包含新值的字符串填充变量。
代码如下:
var d='hello';
d=d+' shit';//执行过程:先将 'hello'赋值一份,然后将 d 中的字符串清空,将字符串 'hello' 和 ' shit'进行拼接,然后赋值给 d 变量。(所以 字符串 的值 一旦 被 创建之后 就不会 改变)
2)toString()方法可将其他数据类型转换成String类型。但如果对null或undefined进行操作,则会报错。
3)String()方法同样能实现toString()的效果,但可以对null和undefined进行操作。
内部原理:先调用toString(),如果可以转换成字符串,就将结果直接返回。否则,再判断是null还是undefined,然后返回‘null'或‘undefined'。
总结:如果确定变量不可能是null或undefined,建议使用toString(),其性能优于String(),因为String()内部还需进行额外判断,从而损耗性能。