JavaScript如何进行类型判断?

前言

在 JS 这样的动态类型语言中,正确地处理不同类型的数据是至关重要的,它不仅仅是确保代码的正确性,还可以提高代码的可读性和可维护性,所以我们应该怎么进行类型判断呢?

本文将探讨 JS 中常用的类型判断方法,包括typeof运算符、instanceof操作符、Object.prototype.toString方法、Array.isArray方法,希望可以帮助到你。

数据类型有哪些?

当然,在进行数据类型判断之前,我们应该了解有哪些数据类型。

原始数据类型:String、Number、Boolean、Symbol、Undefined、Null、BigInt

引用数据类型: Object(引用类型指向一个对象,不是原始值,指向对象的变量是引用变量)

类型判断🔥🔥🔥

1. typeOf

话不多说,直接上代码

javascript 复制代码
let str = 'hello'
let num = 123 
let flag = false 
let und = undefined 
let nu = null 
let big = 123n
let s = Symbol('hello')

let obj = {}
let arr = []
let fn = function() {}
let date = new Date()

// 判断类型
console.log(typeof str); // string
console.log(typeof num); // number 
console.log(typeof flag); // boolean
console.log(typeof und); // undefined
console.log(typeof nu); // object    当年遗留下来的bug
console.log(typeof big); // bigint
console.log(typeof s); //symbol

console.log(typeof obj); //object
console.log(typeof arr); //object
console.log(typeof fn); // function
console.log(typeof date); // object

从例子中我们可以看出typeof 是一种运算符,其右侧接一个表达式,然后它返回一个字符串,表示变量的数据类型。

有些时候,typeof操作符会返回一些令人迷惑的值,比如在判断nu的数据类型时,它居然返回了一个object数据类型,难不成是我们代码写错了吗?不,这其实是一个历史遗留问题。在当年,程序员为了区分引用类型原始类型制定了一个规定,所有的引用类型转换成二进制的时候,前面一定要标注三个零。但是原始类型转换成二进制时前面一定不能有三个零,而 null 也被用 000 来表示。这意味着,尽管 null 不是对象,但其值标签与对象相同。

总结:

  • 对于原始数据类型,除 null 以外,均可以返回正确的结果。
  • 对于引用类型,除 function 返回 function,其他一律返回 object 类型。

2. instanceOf

instanceof 是 JS 中的一个操作符,用于检测一个对象是否是另一个对象的实例,是返回true,否则返回false。一样的场景感受一下:

javascript 复制代码
console.log(obj instanceof Object);// true
console.log(arr instanceof Array);// true
console.log(fn instanceof Function);// true
console.log(date instanceof Date);// true

通过这个场景,我们可以猜测出instanceof是通过原型链查找来进行类型判断的,它只能判断引用数据类型,当我们用instanceof去判断原始类型时,输出值一律为false。

在使用instanceOf的时候我们需要注意一点,因为它是通过原型链查找来进行类型判断的,所以下面的代码返回值都为true。

javascript 复制代码
console.log(arr instanceof Array);// true
console.log(arr instanceof Object);// true

所以当我们需要依据返回结果作出一些操作时需要额外注意!!!比如以返回结果作为if的判断条件,决定是走if还是else时。

这时小伙伴们肯定对于instanceOf是怎么顺着原型链上进行查找感到好奇了吧,接下来我们用段代码来展示一下:

javascript 复制代码
function instanceOf(L,R) {
    let left = L.__proto__  // 获取L的隐式原型
    let right = R.prototype // 获取R的显示原型
    while(left !== null) { // 顺着原型链进行比较查找
        if(left === right) return true 
        left = left.__proto__
    }
    return false
}

console.log(instanceOf([],Array)); //true
console.log(instanceOf([],Object)); // true

总结:

  • 用于检测一个对象是否是另一个对象的实例
  • 只能用于检查对象是否是某个构造函数的实例,不能用于检查原始数据类型。
  • instanceof 操作符返回一个布尔值

3. Object.prototype.toString

Object.prototype.toString 是 JS 中 Object 原型上的方法,它用于返回一个表示对象的字符串。这个方法通常被用于获取对象的内部 [[Class]] 属性,以便更精确地确定对象的类型。同样我们来个场景感受一下:

javascript 复制代码
Object.prototype.toString.call('');   // [object String]
Object.prototype.toString.call(6);    // [object Number]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(1000n); // [object BigInt]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(new Function()); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call({});  // [object Object]

我们从这可以看出Object.prototype.toString是非常精确的进行类型判断,不过我们需要注意的是必须通过Object.prototype.toString.call()来获取,而不是直接使用Object.prototype.toString()

javascript 复制代码
console.log(Object.prototype.toString(123)); // [object Object]
console.log(Object.prototype.toString()); // [object Object]

当直接使用Object.prototype.toString()时,我们返回的都是字符串[object Object],所以为什么要使用call()呢?

在 JS 中,Object.prototype.toString 是一个方法,而不是一个普通的函数。它是定义在 Object.prototype 上的,因此可以被所有对象继承并调用。因此,如果我们想直接调用这个方法,我们可以这样做:

ini 复制代码
var obj = 123;
var result = obj.toString(); // 直接调用对象的 toString 方法 
console.log(obj); // 123

然而,Object.prototype.toString 方法的特殊之处在于,它返回的结果不仅仅取决于调用它的对象,还取决于内部的 [[Class]] 属性。这意味着,直接调用 toString 方法并不能得到我们想要的类型信息。因此,我们需要用 call 或者 apply 来改变方法的执行上下文,以便让它将传入的对象作为自己的上下文,从而获取到正确的类型信息。

ini 复制代码
var obj = 123;
var result = Object.prototype.toString.call(obj); // 通过 call 方法将 obj 作为上下文传入
console.log(obj); // [object Number]

这是官方对于toString步骤的描述:

  1. 如果this值未定义,则返回"[object undefined]"。
  2. 如果this值为空,则返回"[object null]"。
  3. 设0为传递this值作为参数调用ToObject(this)的结果。
  4. 设class为0的内部属性[[class]]的值。
  5. 返回由"[object" 和 class 和 "]" 三部分组成的字符串.

这时小伙伴应该也会好奇call()是怎么把toString掰弯的呢?这里我们也写一段代码来模拟实现一下:

javascript 复制代码
Function.prototype.myCall = function(context) {
    if( typeof this !== 'function') { // this是函数体foo
        throw new TypeError('Mycall is not a function')
    }
    let args = Array.from(arguments).slice(1)   //let args = [...arguments].slice(1)
    context.fn = this // foo的引用
    let res = context.fn(...args) //触发this隐式绑定规则
    delete context.fn //用完就删
    return res
}

var obj = {a:1}
function foo(x,y) {
    console.log(this.a,x+y);
}
foo.myCall(obj,1,2) // 1 3

总结:

  • 返回一个字符串。格式通常为 [object 类型]
  • 用于获取对象的精确类型,特别适用于引用类型的判断。
  • 可以用于检测原始数据类型

4. Array.isArray

Array.isArray()是 JS 中的一个静态方法,可以直接在 Array 对象上调用。用于确定给定的值是否是一个数组,返回值为:true或者 false。例如:

javascript 复制代码
Array.isArray([]); // true
Array.isArray([1, 2, 3]); // true
Array.isArray(new Array()); // true
Array.isArray({}); // false

总结:

  • 它提供了一种更可靠的方式来检查值是否是数组,相比于 instanceof来说更安全,因为它不会受到原型链影响。
  • 在一些旧版本的浏览器中可能不支持该方法,但通常可以通过使用 polyfill 或者其他替代方法来解决。

结尾🌸🌸🌸

类型判断是 JS 开发中的重要一环,通过不断学习和实践,我们可以更好地理解和处理数据。判断数据类型的方法还有很多,我们应该根据实际情况灵活运用。

谢谢各位小伙伴愿意花宝贵的时间阅读这篇文章,如果文章有错误之处,请大家指正,帮助我这位小白成长,谢谢各位小伙伴了!!!!

相关推荐
非著名架构师2 小时前
js混淆的方式方法
开发语言·javascript·ecmascript
多多米10053 小时前
初学Vue(2)
前端·javascript·vue.js
敏编程3 小时前
网页前端开发之Javascript入门篇(5/9):函数
开发语言·javascript
看到请催我学习3 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript
XiaoYu20025 小时前
22.JS高级-ES6之Symbol类型与Set、Map数据结构
前端·javascript·代码规范
儒雅的烤地瓜5 小时前
JS | JS中判断数组的6种方法,你知道几个?
javascript·instanceof·判断数组·数组方法·isarray·isprototypeof
道爷我悟了5 小时前
Vue入门-指令学习-v-on
javascript·vue.js·学习
27669582925 小时前
京东e卡滑块 分析
java·javascript·python·node.js·go·滑块·京东
PleaSure乐事5 小时前
【Node.js】内置模块FileSystem的保姆级入门讲解
javascript·node.js·es6·filesystem
雷特IT6 小时前
Uncaught TypeError: 0 is not a function的解决方法
前端·javascript