一步一步学前端-js基本类型
介绍
js数据类型有7种:string、boolean、number、null、undefined、symbol、object。
根据数据的值存储方式,也可以分成两类:
- 基本类型(string、boolean、number、null、undefined、symbol)
- 引用类型(object)
有一些地方也会把function 与 array 加入到类型中,但是function 与 array本质上是object
string(字符串)
- 可以用单引号双引号引用
- 字面量
- 自带length
nummber(数字)
- 包括整数与浮点数
- NaN非数值类型,用isNaN 可以区分
boolean(布尔)
null 与 undefined
- 变量未赋初值默认为undefined
- null空指针
- undefined == null 为true
symbol
object(包括function 与 array)
类型转换
判断类型
//基本类型除了null 都会显示正常类型
typeof 1 => "number"
typeof '1' => "string"
typeof false => "boolean"
typeof NaN => "number"
typeof null => "object"
typeof undefined => "undefined"
//引用类型除了function,都会正常显示类型名称
typeof [] => "object"
typeof console.log => "function"
typeof {} => "object"
类型转换
- 转换成布尔类型
//除了null、undefined、NaN、''、false、0、+0、-0以外都显示true
Boolean(1) => true
Boolean('1') => true
Boolean(true) => true
Boolean({}) => true
Boolean([]) => true
Boolean(console.log) => true
Boolean(NaN) => false
Boolean(null) => false
Boolean('') => false
Boolean(undefined) => false
Boolean(0) => false
Boolean(+0) => false
Boolean(-0) => false
- 转换为string类型
//除了functiong
String(false) => "false"
String(1) => "1"
String('') => ""
String({}) => "[object Object]"
String([]) => ""
String(undefined) => "undefined"
String(null) => "null"
String(Symbol) => "function Symbol() { [native code] }"
String(NaN) => "NaN"
String(console.log) => "function log() { [native code] }"
- 转换为number类型
//除了空对象与undefined、NaN、不能转化成数字的字符串会显示非数值类型
//0、false、'0'、''、[]、null会转换成0
Number(1) =>1
Number(-0) => -0
Number('-0') => -0
Number(+0) => 0
Number(false) => 0
Number('') => 0
Number([]) => 0
Number(null) => 0
Number('a') => NaN
Number({}) => NaN
Number(NaN) => NaN
Number(undefined) =>NaN
Number(Symbol) =>NaN
Number(console.log) => NaN
- 转换为object类型
//除 undefined 与 null 包装成空对象,[]包装成空数组,其他都可以正确包装对象
Object(1) => Number {1}
Object(0) => Number {0}
Object(-0) => Number {-0}
Object('') => String {""}
Object('-0') => String {"-0"}
Object('0') => String {"0"}
Object(undefined) => {}
Object(null) => {}
Object([]) => []
Object(NaN) => Number {NaN}
Object(false) => Boolean {false}
Object(console.log) => ƒ log() { [native code] }
- 转换为数组
Array(1) => [empty]
Array(false) => [false]
Array(2) => [empty × 2]
Array(true) => [true]
Array('') => [""]
Array('sssssss') => ["sssssss"]
Array({}) => [{…}]
Array([]) => [Array(0)]
Array(null) => [null]
Array(undefined) => [undefined]
Array(console.log) => [ƒ]
数据比较
- 类型相同时
//为undefined 与 null 时
undefined == undefined => true
null == null => true
//数值型比较时,只有在双方值相等是才返回true,如一方为nan则都返回false
1 == 2 => false
1 == NaN => false
1 == 1 => true
NaN == NaN => false
-0 == 0 => true
//字符串比较时,只有在字符序列完全相等时返回true
'' == '' => true
'' == '123' => false
//对象比较时,只有引用相同才会返回true
{} == {} => false
[] == [] => false
var b = {}
var c = b
c == b => true
- 类型不同
null == undefined => true
'1' == 1 => true
'1' == true => true
'1' == NaN => false
'1' == {} => false
'1' == [] => false
'0' == false => true
'-0' == false => true
'x' == true => false
'{}' == {} => false
'false' == false => false
'true' == true => false
'' == null => false//这块好恶心
true == {} => false
true == [] => false
false == {} => false
false == [] => true
false == undefined => false
false == null => false
0 == null => false
0 == undefined => false
0 == [] => true
0 == {} => false
0 == NaN => false
0 == false => true
0 == '' => true
1 == [1] => true
1 == [1,2] => false
[] == false => true
[] == undefined => false
[] == null => false
[] == {} => false
[] == '' => true
[] == 0 => true
[1] == true => true
[1] == '1' => true
[1] == '1 ' => false
[1] == '2' => false
[1] == 1 => true
[1,2] == [] => false
[1,2] == 1 => false
'1 ' == 1 => true
//神奇的隐式转换
[1] == 1 => true
[1] == '1 ' => false
-[1] == [1] => false
[1] == '1' => true
[1,2] == [1,2] => false
[1,2] == '1,2' => true
-'' == 0 => true
-'0' == 0 => true
0 == void 0 => false
void 0 == false => false
void 0 == null => true
void 0 == undefined => true
[] == ![] => true
Number,Boolean,String,Undefined这几种基本类型混合比较时,会将其转换成数字再进行比较
基本类型与复合对象进行比较时,会先将复合对象转换成基本类型(依次调用valueOf与toString方法)再进行比较
undefined被当成基本类型,undefined转换成数字是NaN,因此undefined与除null之外的其它类型值进行比较时始终返回false(注意NaN==NaN返回false)
null被当成复合对象,由于null没有valueOf与toString方法,因此和除了undefined之外的其它类型值进行比较时始终返回false
实战
//判断一个变量是基本类型、对象、NaN、fuction、数组
//写法一
function typeToString(ele) {
if(ele===null) {
return null;
} else if(typeof ele === 'object') {
if(Array.isArray(ele)) {
return 'array';
} else {
return typeof ele;
}
} else if(typeof ele === 'number') {
if(isNaN(ele)) {
return NaN;
} else {
return typeof ele;
}
} else{
return typeof ele;
}
}
//写法二
function typeToString(param) {
if (typeof param == "object") {
if (param == undefined) return null;
if (JSON.stringify(param)[0] == "[") return "array";
else return "object";
} else {
if (typeof param == "number" && isNaN(param)) {
return "NaN";
}
return typeof param;
}
}
//推荐写法
function typeOf(obj) {
const toString = Object.prototype.toString;
const map = {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]' : 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Undefined]': 'undefined',
'[object Null]' : 'null',
'[object Object]' : 'object'
};
return map[toString.call(obj)];
}
四则运算
只有当加法运算时,其中一方是字符串类型,就会把另一个也转为字符串类型。其他运算只要其中一方是数字,那么另一方就转为数字。并且加法运算会触发三种类型转换:将值转换为原始值,转换为数字,转换为字符串。进行其他四则运算时候,都会转换成number类型进行运算
'' + 1 => "1"
'' + false => "false"
'' + undefined => "undefined"
'' + {} =>"[object Object]"
'' + null => "null"
'' + [] => ""
'' + [1,2,3] => "1,2,3"
'' + console.log => "function log() { [native code] }"
'' + new Object() => "[object Object]"
//{} 运算 比较诡异
{} + '1' => 1
经典面试题
0.1 + 0.2 == 0.3 ?
小数算二进制和整数不同。乘法计算时,只计算小数位,整数位用作每一位的二进制,并且得到的第一位为最高位。所以我们得出 0.1 = 2^-4 * 1.10011(0011),那么 0.2 的演算只需要去掉第一步乘法,所以得出 0.2 = 2^-3 * 1.10011(0011)回来继续说 IEEE 754 双精度。六十四位中符号位占一位,整数位占十一位,其余五十二位都为小数位。因为 0.1 和 0.2 都是无限循环的二进制了,所以在小数位末尾处需要判断是否进位(就和十进制的四舍五入一样)。所以 2^-4 * 1.10011…001 进位后就变成了 2^-4 * 1.10011(0011 * 12次)010 。那么把这两个二进制加起来会得出 2^-2 * 1.0011(0011 * 11次)0100 , 这个值算成十进制就是 0.30000000000000004
解决方法:
parseFloat((0.1 + 0.2).toFixed(10))