深入了解 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 值类型的方法,它可以返回一个表示传入值类型的字符串,不受传入值类型是否为原始类型或引用类型的影响。

相关推荐
滚雪球~44 分钟前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语1 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport1 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg1 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全
胡西风_foxww1 小时前
【es6复习笔记】rest参数(7)
前端·笔记·es6·参数·rest
m0_748254881 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
星就前端叭2 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
m0_748234522 小时前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js
Web阿成2 小时前
3.学习webpack配置 尝试打包ts文件
前端·学习·webpack·typescript
噢,我明白了2 小时前
同源策略:为什么XMLHttpRequest不能跨域请求资源?
javascript·跨域