基本数据类型
- number => NaN/Infinity
- string => 单引号/双引号/反引号
- boolean => true/false
- null => 空对象指针
- undefined => 未定义
- bigint => 超过最大安全值使用
- symbol => 创建唯一值
引用数据类型
- object
- function
- 数组对象 (Set属于这里)
- 普通对象 (Map属于这里)
- 正则对象
- Math数学对象
- 日期对象
- prototype原型对象
- ...
数据类型检测
- typeof 检测数据类型的逻辑运算符
- instanceof - 检测是否为某个类的实例
- constructor - 检测构造 函数
- Object.prototype.toString.call - 检测数据类型
typeof
typeof [value] 返回当前值的数据类型
- 返回的结果都是字符串
- 局限性:
- typeof null // "object"
- typeof 不能细分对象类型
typeof null为啥是"object"?
这是遗留的一个bug。不同的对象在底层原理的存储是用二进制表示的,在js中,如果二进制的前三位都为0的话,系统会判定是object类型。null的存储二进制是000,也是前三位,所以系统判定null为Object类型。
- 000:对象类型
- 1:整型
- 010:浮点数
- 100:字符串
- 110:布尔类型
typeof 123; // "number"
typeof 'abc'; // "string"
typeof true; // "boolean"
typeof null; // "object"
typeof {}; // "object"
typeof undefined; // "undefined"
typeof function() {}; // "function"
typeof []; // "object"
typeof Symbol('1'); // "symbol"
typeof BigInt('1'); // "bigint"
typeof NaN; // "number"
typeof Infinity; // "number"
typeof -Infinity; // "number"
其中数组,对象,null都判定为'object',其他都正确。
let a = typeof typeof typeof [12, 23];
console.log(a); // "string"
// typeof typeof "object"
// typeof "string"
- 'number'
Number.MAX_SAFE_INTEGER,js中最大的安全数,超过这个值的,要用bigint处理。(在一个数值后面加n就是bigint类型) // 90071992547409122222n
let res = parseFloat('left: 200px');
if (res === 200) {
alert(200);
} else if (res === NaN) {
alert(NaN);
} else if (typeof res === 'number') {
alert('number');
} else {
alert('Invalid Number');
}
// parseFloat检测里面的字符串(不是字符串就要先转换为字符串类型),从左侧第一个字符开始找有效数字,直到非有效数字为止,返回找到的有效数字。如果一个都没有,那就返回NaN。
// res是NaN
// NaN跟谁都不相等,但NaN属于number类型,因此alert('number');
// alert的内容必须转换为字符串
- symbol
let val = Symbol('00'); console.log(val == val); // true
console.log(Symbol('aa') == Symbol('aa')); // false
instanceof
instanceof可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型【prototype属性】。
2 instanceof Number; // false
true instanceof Boolean; // false
'str' instanceof String; // false
[] instanceof Array; // true
function() {} instanceof Function; // true
{} instanceof Object; // true
由此可知,instanceof只能正确判断引用数据类型,而不能判断基本数据类型。
constructor
(2).constructor === Number; // true
(true).constructor === Boolean; // true
('str').constructor === String; // true
(\[]).contructor === Array; // true
(function() {}).contructor === Function; // true
({}).contructor === Object; // true
constructor有两个作用:
- 判断数据类型
- 对象实例通过contructor对象访问它的构造函数。
需要注意,如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了;
Object.prototype.toString.call()
同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,是因为:
toString是Object的原型方法,而Array,function等类型作为Object的实例,都重写了toString方法。
不同对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法。