一.分类
JS中数据类型的分类:
基本数据类型(简单数据类型):数值型Number,字符串String,布尔值Boolean,Null,未定义Undefined,(ES6新增Symbol(符号)类型)。
引用数据类型(复杂数据类型):Object类型(常用:Array(数组),Function(函数),Date(日期),RegExp(正则表达式)
二.数据类型的判断
由于ECMAScript中的类型系统是松散的,所以就需要一种手段来判断任意变量的数据类型。
操作符 typeof,语法:typeof 变量;返回值是一个小写开头的字符串,有以下的值:
let example;
console.log(typeof example);//返回值为"undefined"
let example = true;
console.log(typeof example);//返回值为"boolean"
let example = 'Hi';
console.log(typeof example);//返回值为"string"
let example = 123;
console.log(typeof example);//返回值为"number"
let example1 = new Object();
let example2 = null;
console.log(typeof example1);//返回值为"object"
console.log(typeof example2);//返回值为"object"
let example = new Function();
console.log(typeof example);//返回值为"function"
let example = Symbol();
console.log(typeof example);//返回值为"symbol"
- 对于基本类型,除 null 以外,均可以返回正确的结果。
- 对于引用类型,除 function 以外,一律返回 object 类型。引用类型中的数组,日期,正则表达式也都有属于自己的具体类型,而 typeof 对于这些类型的处理,只返回了处于其原型链最顶端的 Object 类型(可以通过instanceof来检测其是否是某一类型的实例,如:假设arr是一个已经定义的数组,arr instanceof Array,结果将会返回一个布尔值,arr是Array的实例返回true,否则返回false)
- 对于 null ,返回 object 类型。(因为从逻辑上来讲,null值表示一个空对象指针,因此,null也可 以用来初始化将来要存放对象的变量)
- 对于 function 返回 function 类型。
三.类型转换
(1)其他数据类型转数值
Number(变量):可以把一个变量强制转换成数值类型,可以转换小数,布尔值,遇到不可转换的都会返回NaN(Not a Number).
let example1 = '123.2';//仅由数字构成的字符串
console.log(Number(example1),typeof Number(example1));//123.2 number
let example2 = true;//布尔值,转换后true变为1,false变为0
console.log(Number(example2),typeof Number(example2));//1 number
let example3 = null;//null,为0
console.log(Number(example3),typeof Number(example3));//0 number
//不可转换
// let example4;//undefined,
let example4 = '5asd45';//包含其他字符的字符串
console.log(Number(example4),typeof Number(example4));//NaN number
parseInt(变量),parseFloat(变量):从第一位开始检查,是数字就转换,直到一个不是数字的内容,开头就不是数字直接返回NaN;两者的区别是parseInt(变量)不认识小数点,只能保留整数,而parseFloat(变量)认识一次小数点。
let example1 = '123.4.5Hi67';
let example2 = 'Hi123.4';
console.log(parseInt(example1),typeof parseInt(example1));//123 number
console.log(parseFloat(example1),typeof parseFloat(example1));//123.4 number
console.log(parseInt(example2),parseFloat(example2));//NaN NaN
注意事项:
Number():
1)如果是Boolean值,true和false将分别转换为1和0。
2)如果是数字值,只是简单的传入和返回。
3)如果是null值,返回0。
4)如果是undefined,返回NaN。
5)如果是字符串,遵循下列规则:
如果是字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即“1”变成1,“123”会变成123,而“011”会变成11(前导的零被忽略了);
如果字符串中包含有效的浮点格式,如“1.1”,则将其转换为对应的浮点数值(同样也会忽略前导零);
如果字符串中包含有效的十六进制格式,例如"0xf",则将其他转换为相同大小的十进制整数值;
如果字符串是空的(不包含任何字符),则将其转换为0;
如果字符串中包含除上述格式之外的字符,则将其他转换成NaN.
6)如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用的对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。
由于Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是parseInt()函数。
parseInt():
在转换字符串时,更多的时看其是否符合数值模式。会忽略字符串前面的空格,直至找到第一个非空格字符。
如果第一个字符不是数字字符或都负号,parseInt()就会返回NaN; 也就是说,用parseInt()转换空字符串会返回NaN。
如果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。例如,"1234blue"会被转换为1234,因为"blue"会被完全忽略。类似地"22.5"会被转换为22,因为小数点不是有效的数字字符。
如果字符串以"0x"开头且后跟数字字符,就会将其当作一个十六进制整数;
如果字符串以"0"开头且后跟数字字符,就会将其当作一个八进制整数;
parseInt()函数增加了第二参数用于指定转换时使用的基数(即多少进制)如:parseInt("10",16)//按十六进制解析;parseInt("10",8)//按八进制解析
parseFloat():
与parseInt()函数类似,parseFloat()也是从第一个字符(位置0)形如解析每个字符,而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。也就是说,字符串中的第一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。例如:"22.34.5"将会转换为22.34。
除了第一个小数点有效之外,parseFloat()与parseInt()的第二个区别在于它始终都会忽略前导的零。parseFloat()可以识别前面讨论过的所有的浮点数值格式,也包括十进制整数格式。但十六进制格式的字符串则始终会被转换成0。由于parseFloat()只解析十进制值,因此它没有用第二个参数指定基数的用法。
另外,如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后面都是零),parseFloat()会返回整数。
(2)其他数据类型转字符串
变量.toString():undefinde和null类型不能使用该方法;
String(变量):所有数据类型都能使用;
let example1 = 123;
let example2 = true;
let example3 = null;
let example4;
console.log(example1.toString(),typeof example1.toString());//123 string
console.log(String(example2),typeof String(example2));//true string
// console.log(example3.toString(),example4.toString());//报错
console.log(String(example3),String(example4));//null undefined
(3)其他数据类型转布尔值
(4)隐式类型转换
一元操作符:可以作用于任何值,意思是不限于整数——字符串、布尔值、浮点值,甚至对象都可
let str1 = '6';
let str2 = 'Hi';
let a = true;
let b = false;
let c = 1.1;
console.log(typeof +str1,typeof -str2);//number,number
console.log(++str1,typeof str1);//7 number
console.log(--str2,typeof str2);//NaN number
console.log(--a,typeof a);//0 number
console.log(++b,typeof b);//1 number
字符串连接符与算术运算符隐式转换规则混淆:
字符串连接符“+”:+号两边有一边是字符串,会把其他数据类型调用String()转换成字符串然后拼接。
算术运算符“+”:+号两边有数字,且没有字符串,会把其他类型调用Number()方法转成数字然后做加法计算。
console.log(2 + 'str');//String(2) + 'str' = '2str'
console.log(2 + true);//2 + Number(true) = 2 + 1 = 3
console.log(2 + null);//2 + Number(null) = 2 + 0 = 2
console.log(2 + undefined);//2 + Number(undefinde) = 2 + NaN = NaN
关系运算符:会把其他数据类型转换成number之后再比较关系
当关系运算符两边有一边是字符串时,会将其他类型使用Number()转换,然后比较关系。
当两边都是字符串时,会同时转换成number,然后比较,不过注意一点,这里并不是按照Number()的形式转换成数字,而是按照字符串的Unicode编码来转换成数字,并且当有多个字符时,默认比较第一个字符,如果第一个相同,继续比较第二个,以此类推。
console.log('3' > 10);//false
console.log('3' > '10');//true 此时比较3和1的Unicode编码,51(3)>49(1)
console.log('abccc' > 'aaggg');//true 此时比较b和a的Unicode编码,98(b)>97(a)
// 特殊的
console.log(undefined == undefined);//true
console.log(undefined == null);//true
console.log(null == null);//true
console.log(NaN == NaN);//false NaN与任何数据比较都是false