JS数据类型检测

数据类型检测的方式有哪些

前言:将一些常见类型判断稍些整理一下,此篇为JS数据类型检测的方法

在 JavaScript 中,基本数据类型和对象类型有一个概念叫做 "装箱"(Boxing)。当你尝试在基本数据类型上调用属性或方法时,JavaScript 会自动将基本数据类型转换为对应的对象,然后在对象上执行操作。这是一种隐式的过程 在 Object.prototype.toString.call() 中,这种装箱过程会发生。让我们看看具体的细节:

(这里有利于理解Object.prototype.toString.call()在执行的一些细节处理)

  1. 数字类型(Number)的装箱:

    js 复制代码
    const number = 42;
    const numberObject = new Number(number);
    console.log(Object.prototype.toString.call(numberObject));  // "[object Number]"

    当你尝试调用 Object.prototype.toString.call(number) 时,JavaScript 隐式地将 number 装箱为 Number 对象,然后执行 toString 方法。

  2. 字符串类型(String)的装箱:

    js 复制代码
    const str = 'Hello';
    const stringObject = new String(str);
    console.log(Object.prototype.toString.call(stringObject));  // "[object String]"

    同样,字符串类型也会在需要时被隐式装箱为 String 对象。

这种装箱过程让基本数据类型也可以像对象一样使用一些方法,但需要注意的是,装箱后得到的是一个对象,而不是原始的基本数据类型。在实际开发中,通常直接使用基本数据类型,而不是显式创建对应的包装对象。

(1)typeof(一般用于基本数据类型的判断)

javascript 复制代码
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

其中数组、对象、null都会被判断为object,其他判断都正确。

(2)instanceof

instanceof可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型

instanceof 运算符用于检查对象是否是某个构造函数的实例。然而,对于基本数据类型(如数字、布尔和字符串),它们通常会被封装为对应的包装对象(Number、Boolean 和 String)。当你使用 instanceof 检查基本数据类型时,它实际上是检查包装对象而不是基本数据类型。

javascript 复制代码
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只能正确判断引用数据类型 ,而不能判断基本数据类型。instanceof 运算符可以用来判断一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

(3) constructor

javascript 复制代码
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有两个作用,一是判断数据的类型,二是对象实例通过 constrcutor 对象访问它的构造函数。需要注意,如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了:

ini 复制代码
function Fn(){};
 
Fn.prototype = new Array();
 
var f = new Fn();
 
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true

(4)Object.prototype.toString.call()

Object.prototype.toString.call() 使用 Object 对象的原型方法 toString 来判断数据类型:

vbscript 复制代码
var a = Object.prototype.toString;
 
console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));

同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?

这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串...),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。

(5)数组类型方法判断

  1. Array.isArrray(arr); //返回布尔值
  2. arr.proto === Array.prototype;
  3. Object.prototype.toString.call(arr).slice(8,-1) === 'Array';
  4. arr instanceof Array
  5. Array.prototype.isPrototypeOf()

Array.prototype.isPrototypeOf()

备注: isPrototypeOf()instanceof运算符不同。在表达式object instanceof AFunction中,会检查object原型链是否与AFunction.prototype匹配,而不是与AFunction自身匹配。

结语:此文来自摘录和自己的理解以及后续的一些补充,希望自己也能深刻理解一些方法在底层细节上的处理。

相关推荐
匹马夕阳14 分钟前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?15 分钟前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
桂月二二6 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062068 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb8 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角8 小时前
CSS 颜色
前端·css
九酒8 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae
浪浪山小白兔9 小时前
HTML5 新表单属性详解
前端·html·html5
lee5769 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579659 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter