js-几种数据类型检测方式☂️☂️

143 阅读2分钟

数据类型

1. 数据类型

js的数据类型
undefined、null、string、boolean、number、object、Symbol、BigInt
基本数据类型
undefined、null、string、boolean、number、Symbol、BigInt
引用数据类型
通常用Object代表,普通对象,数组,正则,日期,Math数学函数都属于Object。

Symbol
定义了一个独一无二且不可改变的数据类型,主要是为了解决全局变量可能冲突的问题

所以 Symbol() !== Symbol()

它的构造函数不够完整,所以不能使用new Symbol()创建数据,数据的创建方法Symbol()

BigInt
定一个数字的数据类型,可以表示任意精度的整数,可以安全的操作大整数

使用方法: -整数末尾直接+n:647326483767797n

2. 区别

栈内存堆内存
类型基础数据类型;指向引用数据类型的地址引用数据类型的实例
空间占据空间小占据空间大
大小大小固定大小不固定
内存内存自动分配释放内存由开发者分配释放
数据结构先进后出优先队列,按照优先级排序

数据类型检测

1. typeof

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object    
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object

typeof 判断数据类型会把null、array、{} 都判断成了object;其他判断正确

2. instanceof

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

instanceof 只能正确判断引用数据类型,A instanceof B 判断A是否是B的实例,底层机制是原型的判断

3. constructor

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

constructor 一是判断数据的类型,二是实例对象通过constructor访问它的构造函数;

4、存在问题

当改变了原型,就不能正确判断数据类型了

//函数数据类型
function Fn() { }
// 改变了Fn的原型
Fn.prototype = new Array();
let fn = new Fn();
console.log(fn.constructor === Fn); // flase
console.log(fn.constructor === Array); //true 

5. Obejct.prototype.toString.call()

//1.判断基本类型:
console.log(Object.prototype.toString.call(null));//"[object Null]"
console.log(Object.prototype.toString.call(undefined));//"[object Undefined]"
console.log(Object.prototype.toString.call("abc"));//"[object String]"
console.log(Object.prototype.toString.call(123));//"[object Number]"
console.log(Object.prototype.toString.call(true));//"[object Boolean]"

//2.判断原生引用类型:
//函数类型
function fn() { console.log("test"); }
console.log(Object.prototype.toString.call(fn));//"[object Function]"
//日期类型
var date = new Date();
console.log(Object.prototype.toString.call(date));//"[object Date]"
// 数组类型
var arr = [1, 2, 3];
console.log(Object.prototype.toString.call(arr));//"[object Array]"
//正则表达式
var reg = /[h]at/g;
console.log(Object.prototype.toString.call(reg));//"[object RegExp]"

思考💡:为什么obj.toString()和Obejct.prototype.toString().call()的结果不一样?

Array和Function都是Obejct对象的实例,所以对toString()方法进行了重写,如果想判断正确的数据类型,就得用原型的toString();

思考💡:Obejct.prototype.toString().call(obj).slice(8,-1) === 'Array'?

Obejct.prototype.toString().call(obj) 的值是[object Array] slice(8,-1)表示从第8位开始截取,然后到倒数1位截止,那就是Array