数据类型归纳
数据类型的分类
- 在JS 中,数据类型分为两类: 基本数据类型 和 引用数据类型 两种。
- 基本数据类型 的值,都存放在 变量对象(VO)中。包括有:
number、 string、 boolean、null、undefined、symbol、bigint
- 引用数据类型的值,存放在堆内存中,VO中存放的是引用地址。包括有:
对象类型 object、 函数类型 function
数据类型的转换
- 数据类型在进行运算、比对、数据检测的时候,很多时候,会进行类型的转换。
- 其中 将其余类型转为数字类型 是很常见的情况。在转换过程中,有两种方法:强转换 与 弱转换
- 强转换
- 本质是基于JS的底层转换机制,使用
Number([value])
来完成的。 - 一般的隐式转换(数学运算、isNaN检测)也是基于 Number 来进行转换的,所以也是强转换
- '10px' - 1; => NaN isNaN('12px') => true
- Number的转换规则:
- 布尔类型: Number(true) => 1; Number(false) => 0
- null \ undefined: Number(null) => 0; Number(undefined) => NaN
- symbol\bigint: Number(symbol()) => 报错; Number(10n) => 10;
- 对象:先将对象转为数字,使用 valueOf 进行转换 原始值;没有原始值情况下,则使用 toString 转为 字符串,然后再转为 数字 。
- Number([]) => Number("") => 0
- Number([1]) => Number('1') => 1
- Number([1,2,3]) => Number("1,2,3") => NaN
- Number({}) => Number('[object Object]') => NaN
- 在Number 转换的字符串中,必须保证字符串中的内容全是有效数字,才能转为数字;哪怕有一个不是有效字符,那么也会得到 NaN.
- 本质是基于JS的底层转换机制,使用
- 弱转换
- 是基于一些数学的方法进行转换:
parseInt \ parseFloat
- parseInt \ parseFloat 的转换原则:
- 首先,它们处理的都是字符串。
- 转换顺序是从左往右进行检测。遇到非有效数字字符停止查找
- 如果第一个就不是有效数字字符时候,之间就是 NaN
- 当 value值,不是字符串时候,需要先转为字符串,然后再检测。
- 是基于一些数学的方法进行转换:
parseInt(""); // NaN
Number(""); // 0
isNaN(""); // isNaN(Number(""))=>isNaN(0) false
parseInt(null); // parseInt('null') NaN
Number(null); // 0
isNaN(null); // false
parseInt('12px'); // 12
Number("12px"); // NaN
isNaN("12px"); // true
parseFloat("1.6px")+parseInt("1.2px")+typeof parseInt(null);
// 1.6+1+'number' '2.6number'
isNaN(Number(!!Number(parseInt('0.8'))));
// isNaN(Number(!!Number(0))) isNaN(Number(false)) isNaN(0) false
typeof !parseInt(null) + !isNaN(null);
// 'boolean'+true 'booleantrue'
- 数据类型在遇到 + 号时候:首先需要将左右两侧的转为数字相加,但是在转换过程中,如果遇到字符串,那么就会变为字符串拼接
数据类型比较
- 在JS中,我们经常会遇到 “==” 和 “===” 的情况:
- “===”,代表的是绝对相等,这种情况下,要求:类型一致、值一致 才会相等,如果两侧是两个引用类型,那么都是false。
- “==”, 代表的是弱比对。此时可以允许两边的数据类型不相同。但是转换后的数据类型与值都相等,才能相等。转换规则为:
- null == undefined 在null 是 两个等号的时候:除了 null 和 undefined,其余都是 false. 绝对相等条件下,也是 false
- NaN 和 任何值都不相等,包括自身
- 对象 == 字符串 需要将对象转为字符串
- 其余的:两边都不是数字,先转为数字,在进行运算比较
- 当类型相同,基本类型 绝大情况 为 true。引用类型基本为false
- [] == [] ; {} == {} false
- 因为对象比较的是堆内存地址,开辟了两个堆,堆地址不同,虽然看起来外表一致,但是本质还是不同的。
- 0、NaN、null、undefined、'' 这五个值,可以转为false,其余全是 true。 [] == false; ![] == false; // [] == false; 都转换为数字, // []先转为'', 再转换为数字Number(''),最后得0; // false ==> 0; true;
+ 号的使用
+
在JS中很特殊:可以是数学运算1+1
,也可以是字符串拼接'1' + '1'
- 在
+
的左右两边 出现字符串 或者对象 时候,很多情况下是字符串拼接 - 在对象转数字 进行运算的时候,由于对象转化时候,会调用
valueOf
或者toString
方法,会先转为 字符串,再进而转为数字。但是当转为字符串的时候,就会进行字符串拼接了。很不好意思,它会截胡。 let result = 10 + false + undefined + [] + 'Tencent' + null + true + {}; 10 + false => 10 + 0; 10 + undefined => 10 + NaN NaN + [] => NaN + [].toString() => NaN + "" => 'NaN'; 后续的就变为了字符串拼接 // ==> 'NaNTencentnulltrue[object Object]' let str = 100 + true + 21.2 + null +undefined + 'Tencent' + [] + null + 9 + false; 100 + true + 21.2 + null; // 122.2 // 无字符串和对象,true =》 1 null =》 0 122.2 + undefined; // NaN // undefined => NaN NaN + [number] = NaN NaN + ‘Tencent’ // 'NaNTencent' 进行字符串拼接 'NaNTencent' + [] // 'NaNTencent' // [] => "" 'NaNTencent' + null + 9 + false; // 'NaNTencentnull9false'; - 特殊情况:{}
- {} 在JS中很特殊,存在的情况有:对象、代码块、块级作用域。当遇到 + 号时,如果 带有(),或者写在+ 后面 ,那么会认为是字符串拼接。如果无(),会自认为是数学运算
{}+0?alert('ok'): alert('no'); // no 0+{}?alert('ok'): alert('no'); // ok {}+0, 认为是 代码块{} +0,代码块没有意义,所以就是0 0+{},会是拼接,'0[object Object]'
属性名问题
- 在JS中,经常会遇到 object[key] 的情况。这个key 有很多情况:
- 如果是普通对象的属性名,那么就是基本类型值。
- 如果是对象,需要将对象 转为字符串存储。
- 如果变量名key,是数字或者字符串的情况下,这两个变量名在 “==” 条件下为true,那么我们认为就是一个 变量名
- Symbol 作为基本数据类型,由于具有唯一性,所以属于独立的key
数据类型检测
- 数据类型检测,有且仅有 4种方法
typeof
instanceof
检测是否为某个类的实例constructor
检测构造函数object.prototype.toString.call([value])
完整版检测数据类型。