JS中的数据类型
- 基本数据类型
- symbol
- number
- string
- boolean
- null
- undefined
- 引用数据类型
- object
- {}
- []
- /^$/
- Date
- Math
- ...
- function
- object
数据类型检测
typeof 检测数据类型的逻辑运算符,返回当前值的数据类型 => '数据类型'
- 返回的结果都是字符串
- 局限性
+ typeof null = 'object'
+ typeof 不能区分对象类型({}, [], /^$/, Date, Math, ... => 'object')
instanceof 检测是否为某个类的实例
constructor 检测构造函数
Object.prototype.toString.call 检测数据类型
数据类型转换
强转换(基于底层机制) => Number([value]) => 从左到右查找,只要发现非数字字符则直接返回 NaN
一些隐式转换也是基于 Number 完成的
1. isNaN('12px') => isNaN(Number('12px')) => true
2. 数学运算 '12px'-12 => Number('12px')-12 => NaN
3. 字符串与数字的比较 '12px' == 12 => Number('12px') == 12 => false
...
弱转换(基于一些额外的方法转换) => parseInt([value]) / parseFloat([value]) => 从左到右查找,遇到非数字字符则停止查找;如果第一个字符就是非数字字符则直接返回 NaN
// + 除了数学运算,还有字符串拼接的作用
parseFloat('1.6px') + parseInt('1.2px') + typeof parseInt(null);
//=> 1.6 + 1 + 'null' => 2.6NaN
isNaN(Number(!!Number(parseInt('0.8'))))
//=> false
/*
* 在两边出现字符串(或者对象)的情况下,加号一定是字符串拼接,而不是数学运算
* 对象本身是要转换为数字进行运算的,只不过转换数字的过程中,需要先转换为字符串,才能转换为数字,而一旦转换为字符串,就立即会作为字符串被拼接起来
* 对象转换为字符串,先调用 valueof 获取原始值(一般都是基本类型值),引用类型值则继续调用 toString
* [10] => '10'; [10,20] => '10,20'
*/
let str = 100 + true + 21.2 + null + undefined + 'Tencent' +[] + null + 9 + false;
//=> true => 1, null => 0, 任何数字和 undefined 运算都会变成 NaN , + 遇字符串即转为字符串拼接而非数学运算
//=> NaNTencentnull9false
/*
* 浏览器底层运行的时候,有自己的转换规则
* 1.其它类型值转为数字类型
* 2.其它类型值转为布尔类型
* 3.(==) 的比较
*
* (==) 在进行比较的时候,如果左右两边数据类型不一致,则需要先默认转换为一致的数据类型,然后再进行比较
* (===) 绝对相等,两边类型一致,且值一直才相等,类型不一致即不相等,不再比较值,不会转换
*
* (==) 比较规则
* 1.对象==字符串: 对象转换为字符串 [10]=='10' => true
* 2.null==undefined(===不等), null和任何其它值都不相等 null==0 => false (null是空,0开辟了空间存储)
* 3.NaN 和任何值(包括自己)都不相等
* 4.剩下的情况都是转换为数字类型进行比较
*
* (布尔类型值) 转换规则
* 0 / '' / NaN / null / undefined => false, 其余都为 true
*/
[] == false //=> 转数字 => []: '' -> 0; false: 0 => true
![] == false //=> 运算符优先级, 先!后==; ![]: 转为布尔类型再取反 -> !true -> false; => true
/*
* {} 大括号在 JS 中的情况
* 1.对象
* 2.代码块(判断体,循环体,函数体): 块作用域
*
* {} 在运算符前面 => 在没有使用 () 处理优先级的情况下,不认为是数学运算,加了 () 才是
* {} 在运算符后面 => 认为是数学运算
* 特殊: {} + 0 + {} => [object Object]0[object Object]
*/
{} + 0 ? alert('ok') : alert('no') //=> 此处 {} 是独立的代码快, 与 +0 无关 => 0
//=> +值 和 ++值 都是数学运算,会转换为数字类型
0 + {} ? alert('ok') : alert('no') //=> 0 + Number({}) => NaN => 'no'
/*
* 在 JS 中,对象的属性名是什么数据类型的?
* 普通对象的属性名可以是基本类型值,如果是对象,则需要转换为字符串存储
*/
// example 1
var a = {}, b = '0', c = 0;
a[b] = 'hello'; //=> a['0'] = 'hello'
a[c] = 'hey'; //=> a[0] = 'hey'
console.log(a[b]); //=> 'hey'
// example 2
var a = {}, b = Symbol('1'), c = Symbol('1');
a[b] = 'hello';
a[c] = 'hey';
console.log(a[b]); //=> 'hello'
// example 3
// 普通对象 toString 是调取 Object.prototype.toString,是用来检测数据类型的
var a = [], b = { n: 1 }, c = { m: 2 };
a[b] = 'hello'; //=> a['[object Object]'] = 'hello'
a[c] = 'hey'; //=> a['[object Object]']
console.log(a[b]); //=> 'hey'