JS中的类型判断你真的知道吗?

您所在的位置:网站首页 js类型判断的方法 JS中的类型判断你真的知道吗?

JS中的类型判断你真的知道吗?

2024-04-09 17:21| 来源: 网络整理| 查看: 265

前言

JavaScript是一门动态类型的编程语言,这意味着变量的类型可以在运行时改变。在处理复杂的应用程序时,了解和正确使用类型判断是至关重要的。本文将深入探讨JavaScript中的类型判断,讨论常见的方法、最佳实践以及避免一些常见陷阱的技巧。

在讲解类型判断之前,我们就必须要去了解JavaScript中有哪些数据类型,[在我之前的文章中](JS:给原始类型数据加属性和方法,为什么不报错? - 掘金 (juejin.cn)),曾详细介绍了JS中的两大类数据类型。大家有空可以去看看,之前的文章并没有将类型全部列出,今天顺便在这里补充一下。

1.JavaScript中的数据类型

在开始讨论类型判断之前,我们首先需要了解JavaScript中的数据类型。JavaScript主要分为两大类(七种)数据类型:

基本数据类型(Primitive Types):

undefined null boolean number string symbol

引用数据类型(Reference Types):

object

Array

Function

Date

等等...

如果要对上述数据进行类型判断,你会用什么方法,我知道,你首先想到的肯定是typeof运算符,那我们就先一起去认识一下typeof运算符吧。

2.typeof运算符

JavaScript提供了typeof运算符,可以用来判断变量的类型。它返回一个表示变量类型的字符串。让我们看一些例子:

let a = 10; let b = 'Hello'; let c = true; let d = undefined; let e = Symbol('hello'); console.log(typeof a); // 输出: "number" console.log(typeof b); // 输出: "string" console.log(typeof c); // 输出: "boolean" console.log(typeof d); // 输出: "undefined" console.log(typeof e); // 输出: "symbol"

你是否注意到,上述typeof的判断里,原始数据类型六个里面占了五个,null我并没有写在上面,因为null是特例。看下述代码:

let f = null; console.log(typeof f); // 输出: "object"

为什么会输出object?

在JavaScript早期的实现中,typeof null的结果确实是"object",这是一个已知的历史遗留问题。这是因为在JavaScript的设计中,null被视为一个空的对象指针。为什么不修改这一问题呢?因为如果现在对null进行修改的话,市面上几乎所有程序都得重新书写,所以这种行为在 ECMAScript 的规范中被保留下来,以确保对现有代码的向后兼容性

typeof能判断引用数据类型吗?

看下面案例: let obj = {}; let arr = [1, 2, 3]; let date = new Date(); let fuc = function(){}; console.log(typeof obj); // 输出: "object" console.log(typeof arr); // 输出: "object" console.log(typeof date); // 输出: "object" console.log(typeof fuc); // 输出: "function"

为什么前面三个输出object,而function却是对的呢?

在 JavaScript 的早期版本中,变量的存储方式有两种:原始值(Primitive Values)和引用值(Reference Values)。

原始值: 包括 undefined、null、布尔值、数字和字符串。这些值是直接存储在变量对象中的,因此可以直接访问。 引用值: 包括对象、数组和函数等。这些值存储的是对象的引用,而不是实际的数据。引用值存储在堆内存中,而变量对象中存储的是指向堆内存中实际数据的指针。

由于历史原因,typeof 在设计时被限制为返回一组有限的字符串,表示基本数据类型。在这个设计中,除了函数以外的引用类型都被归类为 "object"。

看起来typeof并不够满足我们的日常需求,下面介绍另一种进行类型判断的运算符。

3.instanceof运算符 instanceof运算符用于检查对象是否是某个特定类型的实例。它只适用于引用类型的判断,例如: let arr = [1, 2, 3]; let func = function() {}; let n = 123 ; let m = null; console.log(arr instanceof Array); // 输出: true console.log(func instanceof Function); // 输出: true console.log(n instanceof Number); // 输出: false console.log(m instanceof Object); // 输出: false

拓展:

你能手搓一个instanceof的实现原理代码吗?

原理是原型链,[我在之前的文章](解析JavaScript原型(二): GPT看见也懵的原型链 - 掘金 (juejin.cn))曾重点介绍过原型链,有不理解的可以去看看。

下面直接展示代码:

function myInstanceof(L,R){ while(L !== null){ if(L.__proto__ === R.prototype){ return true; }else{ L = L.__proto__; } } return false; } const arr = [1] console.log(myInstanceof(arr,Array)) // 输出:true console.log(myInstanceof(arr,Object)) // 输出:true

上述两种方法似乎都存在弊端,并不能实现所有数据类型的判断,那么JavaScript中是否存在可以同时判断所有数据的类型的方法呢?答案是肯定的,这也就是我下面要讲的。

4.Objetc.prototype.toString方法 为了同时判断所有类型,我们可以使用Object.prototype.toString方法。这个方法返回一个表示对象的字符串,其中包含对象的类型信息。但得结合call()方法和slice()方法来实现。如下: let n = 123; let str = 'hello'; let arr = [1, 2, 3]; let func = function() {}; console.log(Object.prototype.toString.call(n)); // 输出: "[object Number]" console.log(Object.prototype.toString.call(str)); // 输出: "[object String]" console.log(Object.prototype.toString.call(arr)); // 输出: "[object Array]" console.log(Object.prototype.toString.call(func)); // 输出: "[object Function]" // 通过字符串截取,可以返回指定类型,如下: console.log(Object.prototype.toString.call(n).slice(8, -1)); // 输出: "Number" console.log(Object.prototype.toString.call(arr).slice(8, -1)); // 输出: "Array" 5. 使用typeof和Object.prototype.toString的结合 在实际开发中,我们通常会结合使用typeof和Object.prototype.toString以得到更全面的类型判断。下面是一个例子: function getType(value) { const type = typeof value; if (type !== 'object') { return type; } return Object.prototype.toString.call(value).slice(8, -1).toLowerCase(); } let x = 10; let y = 'Hello'; let z = [1, 2, 3]; console.log(getType(x)); // 输出: "number" console.log(getType(y)); // 输出: "string" console.log(getType(z)); // 输出: "array"

这样的封装使得我们可以更方便地获取变量的类型,并且能够正确地处理引用类型。

特别提醒:

6. 避免类型判断的陷阱 在进行类型判断时,有一些常见的陷阱需要注意。以下是一些避免这些陷阱的最佳实践: 6.1. 避免使用==进行比较 使用==进行比较时,JavaScript会进行类型转换,可能导致意外的结果。建议使用===进行严格比较,不仅比较值还比较类型。 let num = 10; let strNum = '10'; console.log(num == strNum); // 输出: true console.log(num === strNum); // 输出: false 6.2. 谨慎处理NaN 使用isNaN函数来判断一个值是否为NaN,而不是直接进行等值比较。 6.3. 小心处理null和undefined 在进行类型判断时,要先判断是否为null或undefined,然后再进行其他类型的判断。 结论

JavaScript类型判断是编写健壮代码的重要组成部分。通过了解各种类型判断方法,结合使用它们,我们可以更准确地判断变量的类型,从而提高代码的可读性和可维护性。在实际项目中,根据情况选择合适的类型判断方法,并时刻注意避免常见的陷阱,将有助于提高代码质量。

留言

如果喜欢博主的文章,还请麻烦给点个小赞♥(ˆ◡ˆԅ),如有说的不对的地方,欢迎及时指正哦



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3