深入了解 JavaScript 类型判断

前言

在 JavaScript 中,我们经常需要对不同的数据类型进行判断和处理。JavaScript 提供了多种方法来进行类型判断,包括 typeof、instanceof、Object.prototype.toString.call() 和 Array.isArray() 等。本文将深入探讨这些方法的使用和特点。

typeof 操作符

typeof 操作符是用来判断一个值的类型的基本方法。它返回一个表示该值类型的字符串。在 JavaScript 中,typeof 可以准确地判断除 null 之外的原始类型,并且可以判断一个值是否为函数类型。

js 复制代码
console.log(typeof 'hello');//string
console.log(typeof 123);  //number
console.log(typeof true);//布尔
console.log(typeof undefined);//underfined
console.log(typeof Symbol(1));  //symbol
console.log(typeof 123n);//bigint
console.log(typeof null); // object          null被错误判断为object
console.log(typeof ({}));  // object
console.log(typeof ([]));  // object
console.log(typeof (new Date())); // object
console.log(typeof (function () { }))  // function

需要注意的是,typeof null 返回的是 "object",这是由于历史原因而产生的一个错误。因此,在判断一个值是否为 null 时,不能仅仅使用 typeof

另外,typeof 对于引用类型(如数组、对象)的判断并不准确,它会将数组和对象都判断为 "object" 类型。如果需要判断一个值是否为数组,可以使用 Array.isArray() 方法。

总结起来,typeof 是一种简单但有限的类型判断方法,在处理原始类型和函数类型时较为准确,但对于引用类型的判断有一定的局限性。

Array.isArray()方法。

Array.isArray() 是 JavaScript 中用于判断给定值是否为数组的方法。它返回一个布尔值,如果给定值是数组,则返回 true,否则返回 false。

js 复制代码
let arr = [];
Array.isArray(arr); // true

let obj = {};
Array.isArray(obj); // false

Array.isArray("hello"); // false

Array.isArray() 方法可以用来区分数组和其他类型的对象,它在处理复杂的数据结构时非常有用。无论给定值是通过何种方式创建的,Array.isArray() 都可以准确地判断它是否为数组类型。

总之,Array.isArray() 是一种简单而强大的工具,用于确定一个值是否为数组类型。在编写 JavaScript 代码时,特别是处理数据集合时,这个方法经常会派上用场。

instanceof 操作符

在JavaScript中,instanceof是一种常用的引用类型判断方法,不能判断简单类型。它的语法如下:

js 复制代码
object instanceof constructor

其中,object 是要检查的对象,constructor 是要检查的类。如果 object 是 constructor 的实例,则返回 true,否则返回 false。

js 复制代码
let obj = {}
let arr = [1, 2]
let date = new Date()
let fn = function () { }
console.log(obj instanceof Object); // ture
console.log(arr instanceof Array);  // true   arr.__proto__ === Array.prototype
console.log(date instanceof Date);// true
console.log(arr instanceof Object); // true   arr.__proto__.__proto__ === Object.prototype
console.log(fn instanceof Object);

它的原理是通过原型链查找方式来进行判断,,因此它可能会受到原型链修改的影响。如果 constructor 的原型链被修改过,那么 instanceof 的判断结果也会受到影响。

总之,instanceof 是一种用于检查对象类型的方法,它可以用来判断一个对象是否为某个类的实例。需要注意的是,它只适用于对象和函数类型,并且可能会受到原型链的影响。

当在面试中被要求能不能手写一个instanceof 判断代码时

只要理解了instanceod的工作原理,是可以手动实现一个简单的 instanceof 判断的。

js 复制代码
function myInstance(L, R) {
 let left = L.__proto__
 let right = R.prototype

 while (left !== null) {
     if (left === right) {
         return true
     }
     left = left.__proto__
 }
 return false
}

console.log(myInstance({}, Array));

console.log(myInstance([], Object))

上述代码实现了一个名为 myInstanceOf 的函数。它接受两个参数:L 是要检查的对象,R 是要检查的类。函数会遍历对象的原型链,直到找到与 R.prototype 相等的原型,或者到达原型链的顶部(即 null),然后返回相应的判断结果。

Object.prototype.toString.call()

Object.prototype.toString.call() 方法是一种比较准确的判断 JavaScript 值类型的方法。该方法可以返回一个表示传入值类型的字符串,不受传入值类型是否为原始类型或引用类型的影响。

语法如下:

js 复制代码
Object.prototype.toString.call(value)

其中,value 是要检查的值。

js 复制代码
console.log(Object.prototype.toString.call(123)); // 输出:[object Number]
console.log(Object.prototype.toString.call('hello')); // 输出:[object String]
console.log(Object.prototype.toString.call(true)); // 输出:[object Boolean]
console.log(Object.prototype.toString.call(function(){})); // 输出:[object Function]
console.log(Object.prototype.toString.call([])); // 输出:[object Array]
console.log(Object.prototype.toString.call({})); // 输出:[object Object]
console.log(Object.prototype.toString.call(null)); // 输出:[object Null]
console.log(Object.prototype.toString.call(undefined)); // 输出:[object Undefined]
"

在实际使用中,Object.prototype.toString.call() 通常与 typeof 操作符、instanceof 操作符、Array.isArray() 等方法组合使用,以便更准确地判断值的类型。

需要注意的是,当我们直接使用toString方法时,会返回对象的字符串形式,而不是对象的类型信息。

js 复制代码
console.log([1, 2, 3].toString()); // 输出:"1,2,3"
console.log((123).toString()); // 输出:"123"

总之,Object.prototype.toString.call() 是一种比较准确的判断 JavaScript 值类型的方法,它可以返回一个表示传入值类型的字符串,不受传入值类型是否为原始类型或引用类型的影响。

相关推荐
无双_Joney几秒前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(功能篇)
前端·后端·nestjs
在云端易逍遥2 分钟前
前端必学的 CSS Grid 布局体系
前端·css
EMT2 分钟前
在 Vue 项目中使用 URL Query 保存和恢复搜索条件
javascript·vue.js
ccnocare4 分钟前
选择文件夹路径
前端
艾小码4 分钟前
还在被超长列表卡到崩溃?3招搞定虚拟滚动,性能直接起飞!
前端·javascript·react.js
闰五月5 分钟前
JavaScript作用域与作用域链详解
前端·面试
泉城老铁8 分钟前
idea 优化卡顿
前端·后端·敏捷开发
前端康师傅8 分钟前
JavaScript 作用域常见问题及解决方案
前端·javascript
司宸10 分钟前
Prompt结构化输出:从入门到精通的系统指南
前端