JavaScript类型判断方法:避免常见陷阱,写出更可靠的代码

JavaScript 是一种动态弱类型的语言,变量被赋值时可以自动推断其类型,这在一定程度上方便了开发,但同时也可能导致一些类型相关的问题。为了解决这些问题,我们需要使用 JavaScript 中的类型判断方法。今天我们将详细讲解各种方法和使用它们需要注意的问题。

数据类型

先来回顾一下数据类型:

- 原始类型:

  1. number数值型: let num = 123
  2. string字符串:let str = 'hello'
  3. boolean布尔型:let bool = true
  4. undefined未定义: let un = undefined
  5. null空值:let nl = null

在es6后,还新增了两种原始类型:

6. Symbol类型:let s = Symbol(123)

它表示一个独一无二的值,可以用作对象属性的键。Symbol值是不可变且唯一的,每个Symbol值都是独立的,不会和其他任何值相等。

创建Symbol可以使用Symbol()构造函数或Symbol.for()方法。Symbol()构造函数创建的Symbol是临时的,而Symbol.for()方法创建的Symbol是全局的,它会先在全局Symbol注册表中搜索键为传入参数的Symbol,如果找到则返回该Symbol,否则创建一个新的Symbol并添加到全局Symbol注册表中。

Symbol可以作为对象的属性键,用于解决属性名冲突的问题。由于每个Symbol值都是唯一的,所以可以保证不会与其他属性名冲突。例如:

ini 复制代码
const mySymbol = Symbol();
const obj = {};

obj[mySymbol] = 'Hello Symbol';
console.log(obj[mySymbol]); // 输出 'Hello Symbol'

需要注意的是,Symbol值并不具有字符串的隐式转换功能,如果需要显示转换为字符串,可以使用Symbol的toString()方法或将其与一个空字符串进行连接。

7. BigInt大整型:let big = 123n

BigInt类型用于存储超出JavaScript固有数字限制的大整数。JavaScript中的Number类型可以精确表示最大值为2^53-1的整数值,超过这个值的整数计算可能会产生精度丢失。而BigInt类型则可以表示任意大的整数,不受JavaScript固有数字限制的影响。

使用BigInt类型可以通过在整数值后面加上n来创建,例如:const bigNum = 123456789012345678901234567890n;

BigInt类型支持包括加减乘除、位运算等在内的多种算术运算和比较操作。需要注意的是,在进行数值运算时,BigInt类型只能与其他BigInt类型进行运算,不能与普通Number类型混合运算。

例如,可以使用以下代码创建两个BigInt类型的变量并进行加法运算:

ini 复制代码
const bigNum1 = 123456789012345678901234567890n;
const bigNum2 = 987654321098765432109876543210n;
const result = bigNum1 + bigNum2;
console.log(result);

- 引用类型:

  1. Object对象:let obj = {}
  2. Function函数:let fn = function(){}
  3. Array数组:let arr = []
  4. Date日期:let date = new Date()

(本文类型判断中引用类型就只讨论这几种,还有其他正则表达式等就不提了)

类型判断

接下来我们进入正题,类型判断有哪几种方法呢?

1. typeof

用typeof进行类型判断,需要注意以下两点:

  1. typeof可以准确判定原始类型,除了null,用typeof判断null会输出object。

  2. typeof不能判定引用类型,除了function,用typeof判断引用类型都会输出object,但除了function,function类型它可以判断出来。

    javascript 复制代码
     console.log(typeof 'hello'); 
     console.log(typeof 123);
     console.log(typeof true);
     console.log(typeof undefined);
     console.log(typeof Symbol(1));
     console.log(typeof 123n);
     console.log(typeof null);  
    
     console.log(typeof ({})); //object
     console.log(typeof ([])); //object
     console.log(typeof (new Date())); //object
     console.log(typeof (function(){})); //function
     

输出结果是:

2. instanceof

使用instanceof运算符来判断是否是某种类型需要知道的是:

  1. 只能判断引用类型,当我们用instanceof去判断原始类型时,输出值一律为false。

  2. instanceof的原理是通过原型链的查找来判断的。所以当我们去判断数组、函数、日期类型是否为对象类型时,也会返回true。

    javascript 复制代码
     let str = 'hello'
     console.log(str instanceof String); //不能判断,专门为引用类型打造的
     
     let obj = {}
     let arr = [1,3]
     let date = new Date()
     let fn = function(){}
    
     console.log(obj instanceof Object);
     console.log(arr instanceof Array);
     console.log(date instanceof Date);
     console.log(fn instanceof Function);
    
     console.log(arr instanceof Object);// 输出true

输出结果为:

我们来看一下instanceof的原理,如果有对原型链不太懂的掘友可以先去看下我这篇 JavaScript原型与原型链:理解核心概念,构建强大的前端技能哦,里面有详细讲解。

在JavaScript中,每个对象都有一个原型(prototype),原型又是一个对象,同时也有自己的原型。这样形成了一个原型链,直到最顶层的原型为null。

instanceof操作符会检查对象的原型链,看是否能在链上找到与指定构造函数的原型相匹配的原型。

如果在原型链中找到了匹配的原型,instanceof返回true;如果顺着原型链一直往上找到null都没有找到匹配的原型,则返回false。

javascript 复制代码
//instanceof 的原理

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
}

3. Object.prototype.toString()

Object.prototype.toString() 方法是 JavaScript 中最古老的方法之一,它可以比较准确地判断一个值的类型,包括原始类型和对象类型。当我们调用 Object.prototype.toString() 方法时,会根据传入的值的 [[Class]] 内部属性的值返回一个形如 "[object class]" 的字符串,其中 class 是实际类型的字符串表示。

typescript 复制代码
let str = 'hello'
let num = 123
let bigint = 123n

let obj = {}
let arr = [1,2]

console.log(Object.prototype.toString.call(str));
console.log(Object.prototype.toString.call(num));
console.log(Object.prototype.toString.call(bigint));
console.log(Object.prototype.toString.call(obj));
console.log(Object.prototype.toString.call(arr));

输出结果为:

需要注意的是,Object.prototype.toString() 方法返回的是一个形如 "[object class]" 的字符串,我们可以通过对返回结果进行处理来判断类型,将返回结果进行字符串切割。以代码里的str = 'hello'为例:

vbnet 复制代码
console.log(Object.prototype.toString.call(str).slice(8,-1));
// 进行切割后将由输出[object String]变为输出String

如果想要详细了解这个方法的原理,可以点此15.2.4.2Object.prototype.toString ( )官方文档里去查看。

4. Array.isArray()

Array.isArray() 方法用于判断一个值是否为数组类型,它只能用于数组类型的判断,对于其他引用类型则返回 false。

以下是使用 Array.isArray() 方法进行数组类型判断的示例代码:

ini 复制代码
let arr = [];

console.log(Array.isArray(arr)); // 输出 true

需要注意的是,Array.isArray() 方法位于 Array 对象上,而不是在它的原型上,因此我们可以直接调用该方法来进行数组类型的判断,但不能arr.isArray()这样去用。

今天类型判断的方法到这就讲完啦!欢迎下次再来一起学习哦ヾ(◍°∇°◍)ノ゙

相关推荐
迦南giser2 分钟前
前端性能——传输优化
前端
小白_ysf6 分钟前
Vue 中常见的加密方法(对称、非对称、杂凑算法)
前端·vue.js·算法
2501_944448001 小时前
Flutter for OpenHarmony衣橱管家App实战:支持我们功能实现
android·javascript·flutter
人工智能训练6 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪7 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi9228 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233228 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头882110 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas13610 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠10 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6