六种基本数据类型(String、Number、Null、Undefined、Symbol、Boolean)
判断数据类型的方法
1. typeof
| 数据类型 | typeof返回的字符串 |
|---|---|
| Undefined | undefined |
| Boolean | boolean |
| Number | number |
| BigInt | bigint |
| String | string |
| Null | object |
| Symbol | symbol |
| Function | function |
| 其他对象 | object |
console.log(typeof 1);// number
console.log(typeof NaN);// number
console.log(typeof 42n);// bigint
console.log(typeof 'hello');// string
console.log(typeof ('hello'+1));// string - 类型装换
console.log(typeof undefined);// undefined
console.log(typeof Undefined);// undefined
console.log(typeof Symbol('foo'));// symbol
console.log(typeof true);// boolean
console.log(typeof Boolean('1'));// boolean
console.log(typeof !('1'));// boolean - !取非类型转换
console.log(typeof null);// object - 特殊情况
console.log(typeof [1,2,3]);// object - Array是内置对象
console.log(typeof /0-9/g);// object - RegExp是内置对象
console.log(typeof new Date());// object - Date是内置对象
console.log(typeof function(){});// function
console.log(typeof class C{});// function
- 总结:typeof基本能识别出基本数据类型(null是个特殊),但是要想识别对象并不靠谱
2. instanceof
- instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
console.log(1 instanceof Number);// false
console.log(new Number(1) instanceof Number);// true - Number是Object派生的对象
console.log(true instanceof Boolean);// false
console.log(new Boolean(true) instanceof Boolean);// true - Boolean是Object派生的对象
console.log('hello' instanceof String);// false
console.log(new String('hello') instanceof String);// true - String是Object派生的对象
console.log([] instanceof Array);// true - 引用类型可以识别
console.log(function(){} instanceof Function);// true - 引用类型可以识别
console.log({} instanceof Object);// true
console.log(new Object() instanceof Object);// true
console.log(Object.create(null) instanceof Object);
// false - Object.create(null)创建的对象没有原型
console.log(null instanceof Object);// false
- 总结:instanceof对字面量创建和构造函数创建的基本数据类型分了两种情况,原理是查看原型链上是否存在目标
3. constructor属性:查看构造函数
console.log((1).constructor === Number);// true
console.log(('hello').constructor === String);// true
console.log(([]).constructor === Array);// true
console.log(({}).constructor === Object);// true
console.log((function(){}).constructor === Function);// true
console.log((true).constructor === Boolean);// true
console.log(null.constructor);// 报错,不能读到null的构造函数
console.log(undefined.constructor);// 报错,不能读到undefined的构造函数
console.log((Object.create(null)).constructor);// undefined,Object.create()创建的对象没有构造函数
- 总结:constructor判断类型是基于有效对象的构造函数,constructor属性是可读可写的,当被显式修改时就出现了预测之外的结果
function A(){};
function B(){};
A.prototype.constructor = B;// 显式修改了A.prototype的constructor属性
console.log((new A()).constructor === A);// false
console.log((new A()).constructor === B);// true
4. Object.prototype.toString.call() (目前为止最靠谱的类型判断方法)
- 原理:Object.prototype.toString()返回表示调用者的字符串,也就是调用时this指针指向的,用call显式修改this
let tostring = Object.prototype.toString;
console.log(tostring.call('hello'));// [object String]
console.log(tostring.call(111));// [object Number]
console.log(tostring.call(null));// [object Null]
console.log(tostring.call(undefined));// [object Undefined]
console.log(tostring.call(true));// [object Boolean]
console.log(tostring.call(Symbol()));// [object Symbol]
console.log(tostring.call({}));// [object Object]
console.log(tostring.call(Object.create(null)));// [object Object]
console.log(tostring.call([1,2,3]));// [object Array]
console.log(tostring.call(new Date()));// [object Date]
console.log(tostring.call(/\d/));// [object RegExp]
console.log(tostring.call(new Error()));// [object Error]
总结:最好的判断类型方法Object.prototype.toString.call(),完美解决所有情况。