JavaScript中的数据类型,以及四种类型判断的好方法

JavaScript 中的数据类型分为两大类

原始数据类型(Primitive Data Types)和引用数据类型(Reference Data Types)。以下是具体的种类:

原始数据类型

Number:表示整数和浮点数,例如 42, 3.14。

String:表示文本,例如 "Hello, World!"。

Boolean:逻辑值,只有 true 和 false 两个值。

Undefined:表示变量已被声明但尚未被赋予任何值。

Null:表示一个刻意的空值或缺少值,它只有一个值 null。

Symbol(ES6 新增):符号类型,是唯一且不可变的值,常用于对象的键,以避免键名的冲突。

BigInt(ES10 新增):可以安全地存储、操作大整数,超过 Number.MAX_SAFE_INTEGER 的整数。

引用数据类型

Object:复合数据类型,可以包含多个键值对,包括数组(Array)、函数(Function)、日期(Date)、正则表达式(RegExp)等都是基于对象的。

Function:函数本身也是一种对象,可以作为值来传递和赋值。

Array:特殊类型的对象,用于存储有序的元素集合。

Date:用于处理日期和时间。

RegExp:正则表达式对象,用于匹配字符串中的模式。

Map, Set, WeakMap, WeakSet(ES6 新增):这些是新的集合类型,提供了更灵活的数据结构。

Promise(ES6 新增):用于异步计算。

Buffer(Node.js 特有):处理二进制数据。

Error:错误对象,用于表示程序运行时发生的错误。

Class(ES6 新增):用于实现面向对象编程中的类。

每种数据类型都有其特定的用途和操作方式,理解它们的特性对于编写高效、可靠的JavaScript代码至关重要。

判断方法

typeof

  1. 可以判断除了null以外的所有原始类型
  2. 无法判断除了function以外的所有引用类型
  • typeof的判断原理是:将之转换为二进制后看其前三位是不是0, 除了函数function,所有的引用类型的二进制前三位都是0,而null的二进制是000000000
  1. 基本数据类型检测 :
    • 对于原始数据类型(如numberstringbooleanundefinedsymbol(ES6引入)、bigint(ES10引入)),typeof会直接返回其类型名称(如"number""string"等)。
    • 而对于undefined,它会返回"undefined"
  2. 对象和数组检测 :
    • 对于对象(包括普通对象、数组、函数等),typeof一律返回"object"。注意,尽管函数是一种特殊的对象,但使用typeof检查函数时,会返回"function",这是typeof的一个特例。
  3. null值的特殊性 :
    • 对于null值,typeof会返回"object",这是一个历史遗留问题,通常被认为是JavaScript的一个设计缺陷。
  4. 示例:
js 复制代码
   console.log(typeof 42);      // 输出: "number"
   console.log(typeof "Hello");  // 输出: "string"
   console.log(typeof true);    // 输出: "boolean"
   console.log(typeof undefined); // 输出: "undefined"
   console.log(typeof Symbol()); // 输出: "symbol"
   console.log(typeof BigInt(42)); // 输出: "bigint"
   console.log(typeof {});       // 输出: "object"
   console.log(typeof []);       // 输出: "object"
   console.log(typeof function(){}); // 输出: "function"
   console.log(typeof null);     // 输出: "object"

构造个函数专门来判断是否为对象

通过typeof方法可判断输入的是否为对象,还要小心不能为null

js 复制代码
function isObject(obj){
    if(typeof obj === 'object' && obj !== null){
        return true
    }else{
        return false
    }
}
console.log(isObject({}));//ture

instanceof

  1. 只能用来判断引用类型
  • 通过原型链的查找来判断
  1. 基本数据类型检测 :
    • 对于原始数据类型instanceof会直接返回flase
    • 而对于undefined,它会直接报错。
  2. 对象检测 :
    • 对于对象(包括普通对象、数组、函数等),instanceof在判断完是否正确后返回ture
    • 数组(Array)、函数(Function)、日期(Date)、正则表达式(RegExp)等都是基于对象的,通过查找到原型链,最后都能找到Object上,因此instanceof在判断以上内容时可以成功判定为Object
js 复制代码
let str = 'str'
let num = 1    
let flat = true   
let un = undefined     
let nu = null     

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

console.log(str instanceof String); // false
console.log(num instanceof Number); // false
console.log(flat instanceof Boolean);   // false
console.log(un instanceof undefined);  //报错,后面必须是大写即构造函数

console.log(obj instanceof Object);// true
console.log(arr instanceof Array);// true
console.log(func instanceof Function);// true

console.log(arr instanceof Object);// true

手搓一个与之作用相当的函数

即判断左边的隐式原型是否与对应右边的显式原型相等

js 复制代码
function myInstanceof(L,R) {
    while(L !== null){
        if(L.__proto__ === R.prototype){
            return true
        }
        L = L.__proto__
    }
    return false
}
var arr = []
console.log(myInstanceof(arr, Array));// true

Object.prototype.toString()

先来回忆一下toString()方法

  1. 对象的toString()
  2. 数组的toString():将数组中的每个元素都转换为字符串,然后用逗号拼接起来
  3. 其他的toString():直接将值修改为字符串字面量

开发者可以自定义对象的 toString() 方法

js 复制代码
let person = {
    firstName: "John",
    lastName: "Doe",
    toString: function() {
      return this.firstName + " " + this.lastName;
    }
  };
  console.log(person.toString()); // 输出: "John Doe"

数组的toString()

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

函数的toString()

js 复制代码
function sayHello(name) {
    return "Hello, " + name + "!";
  }
  console.log(sayHello.toString());
  // 输出可能为: "function sayHello(name) {\n    return \"Hello, \" + name + \"!\";\n}"

Object.prototype.toString(x)

  1. 如果 toString() 接受的值是 undefined则返回 [object Undefined]
  2. 如果 toString() 接受的值是 null则返回[object Null]
  3. 调用 ToObject(x) 将x转为对象,此时得到的对象内部一定拥有一个属性:[[Class]],该属性[[Class]]的值就是x的类型。
  4. 设,class 是[[Class]]的值
  5. 返回由"[object ", class, and "]"拼接组成的字符串

基本用法

当你直接调用toString()方法在一个对象上调用时,如果没有被覆盖,它会返回一个表示该对象的字符串。但是,直接使用toString()可能会因为对象自定义了toString方法而得到非预期的结果。因此,推荐使用Object.prototype.toString.call()Object.prototype.toString.apply()来避免这种情况,确保总是调用到原始的toString实现。

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

console.log(Object.prototype.toString.call(array)); // 输出: "[object Array]"

返回格式

对于大多数内置对象,Object.prototype.toString.call()会返回一个形如"[object Type]"的字符串,其中Type是对象类型的一个小写形式描述。例如:

  • 数组: [object Array]
  • 字符串: [object String]
  • 布尔值: [object Boolean]
  • 数字: [object Number]
  • 空对象: [object Object]
  • 函数: [object Function]
  • 正则表达式: [object RegExp]
  • 日期: [object Date]
  • Error对象: [object Error]
  • Map: [object Map]
  • Set: [object Set]
  • WeakMap: [object WeakMap]
  • 等等

示例

js 复制代码
javascript
console.log(Object.prototype.toString.call([]));       // 输出: "[object Array]"
console.log(Object.prototype.toString.call(new Date)); // 输出: "[object Date]"
console.log(Object.prototype.toString.call(/abc/));    // 输出: "[object RegExp]"

创建一个函数来直接输出该输入的类型种类

Object.prototype.toString.call()会返回一个形如"[object Type]"的字符串,而这里我们只需要得到object后的数据,于是可直接使用slice方法删去不需要的数据

js 复制代码
function type(x) {
    let res = Object.prototype.toString.call(x);// [object String]
    return res.slice(8, res.length-1);// String
    //return res.slice(8, -1)
}

type('asdfg')// String
type(123)// Number
type([])// Array
console.log(type(123));

作为类型检查工具

由于其能提供精确的类型信息,Object.prototype.toString.call()常被用作一个强大的类型检查工具,特别是在需要区分数组、正则表达式等特殊对象类型时。

Array.isArray()

只能判断数组,ture false

js 复制代码
  let arr = [];
  console.log(Array.isArray(arr)); // 输出: true

总结

首先我们需要知道JavaScript中数据类型分为两大类原始数据类型和引用数据类型,接着可以使用许多方法来判断其中的具体类型。

  • typeof可以判断除了null以外的所有原始类型,无法判断除了function以外的所有引用类型,直接输出类名
  • instanceof只能用来判断引用类型,输出ture or false
  • Array.isArray()只能判断数组,输出ture or false
  • Object.prototype.toString()是最为全面的判断方法,用它就没错,输出[object 类型名]
相关推荐
GISer_Jing几秒前
前端面试常考题目详解
前端·javascript
Boilermaker19921 小时前
【Java EE】SpringIoC
前端·数据库·spring
中微子1 小时前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10241 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y2 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁2 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry2 小时前
Fetch 笔记
前端·javascript
拾光拾趣录2 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟2 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan2 小时前
一文了解什么是Dart
前端·flutter·dart