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 类型名]
相关推荐
web行路人4 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0015 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼92124 分钟前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂26 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
长弓三石35 分钟前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
小马哥编程36 分钟前
【前端基础】CSS基础
前端·css
嚣张农民1 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二1 小时前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y5236481 小时前
Javascript监控元素样式变化
开发语言·javascript·ecmascript