js的数据类型、数据类型判断、数据类型转换

100 阅读7分钟

一、js的数据类型

本文将介绍 JavaScript 的 8 种数据类型,结合代码对每种数据类型进行总结归纳。

1.基本数据类型

  • Undefined:未定义型 一个变量声明了但是未赋值的情况下就是undefined;
  • Null:空型 一般用来清空变量,也起了占位作用
  • String:字符型 凡是被双引号或单引号包裹起来的都叫做字符型,字符串有length属性。
  • Number:数值型 包含整数和浮点数(浮点数数值必须包含一个小数点,且小数点后面至少有一位数字)两种值。 (1)NaN:非数字类型。 特点:①涉及到的任何关于NaN的操作,都会返回NaN ② NaN不等于自身。 (2)isNaN() :用于检查其参数是不是数值,得到的结果是一个布尔值,不是数值返回true,是数值返回false。
  • Boolean:布尔型,只有true和false两个值。
  • Symbol:代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突的问题。
  • BigInt:是一种数字类型的数据,它可以表示任意精度格式的整数,使用BigInt可以安全地存储和操作大整数,即使这个数已经超出了Number能够表示的安全整数范围。

2.引用数据类型

  • Object:表示键值对的集合,是 JavaScript 中所有对象的基础。除了基本数据类型之外的所有类型都是对象类型,这包括:
Array:表示元素的有序集合。 
Function:表示函数。 
Date:表示日期和时间。 
RegExp:表示正则表达式。
其他内置对象,如 MapSetWeakMapWeakSet 等以及用户自定义类型。

二、基本数据类型和引用数据类型的特点

1.基本数据类型

  • 基本数据类型的值直接存储在栈内存中,占据空间小、大小固定。
  • 基本类型类型的值被赋给另一个变量时,实际上是创建了该值的一个副本,两个变量分别持有各自的值,其中任一变量的值修改不会影响到另一个变量的值
  • 比较基本数据类型时,是比较它们的值是否相等
let name="abc";
let age=18;

// 赋值
let a=18;
let b=a;
a=456;

console.log(b); // 18
console.log(a); // 456

// 比较
console.log(a === b) // false
console.log(age === b) // true

存储结构如下:

nameabc

栈区中包含了变量的变量的标识符和变量的值

2.引用数据类型

  • 引用数据类型的值存储在堆内存中,占据空间大,大小不固定。当创建一个引用类型的变量时,栈内存中只会存储指向堆内存中实际数据的引用地址,而不是数据本身。
  • 引用数据类型赋值是按引用进行的,当把一个引用类型的值赋给另一个变量时,实际上是复制了引用,两个变量指向同一个对象,对其中一个的修改会影响另一个
  • 比较引用数据类型时,是比较它们的引用是否指向相同的内存地址。
let obj={
  name:"abc",
  age:18,
}

// 赋值
let obj2=obj;
obj2.name="def";
console.log(obj.name); // def

// 比较
let name="abc";
console.log(obj.name===name) // false 
console.log(obj.name==obj2.name) // true

存储结构如下:

nameabc
obj

堆中存的是实体的地址,栈中存的是一个指向堆内存的引用

三、js的类型判断的方法

1.使用typeof操作符

  • typeof操作符可以用来检测基本数据类型,比如字符串、数字、布尔值、函数等,但对于对象和数组的区分不够准确。
  • 优点:简单快捷,适用于基本数据类型(如字符串、数字、布尔值)和函数的判断。缺点:对于对象类型的判断不够准确,无法区分数组和对象,null 被识别为 "object"(这是一个历史遗留问题)。
console.log(typeof "Hello");   // "string"
console.log(typeof 42);        // "number"
console.log(typeof true);      // "boolean"
console.log(typeof function(){}); // "function"
console.log(typeof {});        // "object"
console.log(typeof []);        // "object"
console.log(typeof null);      // "object" (注意:null被错误地归类为"object")
console.log(typeof undefined); // "undefined"

2.使用instanceof操作符

  • instanceof操作符用于检测对象的构造函数,可以判断一个对象是否是某个特定类型的实例。
  • 优点:可以精确判断对象是否属于指定的构造函数。缺点:在多个全局执行环境或框架中使用时可能会出现问题,不适用于原始数据类型的判断。
let arr = [];
console.log(arr instanceof Array); // true

let obj = {};
console.log(obj instanceof Object); // true

3.使用Array.isArray()方法

  • Array.isArray()方法专门用于检测一个对象是否为数组。
  • 优点:精确判断一个对象是否为数组。缺点:在某些较旧的浏览器版本中可能不被支持。
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
let obj = {};
console.log(Array.isArray(obj)); // false

4.使用Object.prototype.toString.call()

  • 这是一种通用且精确的方法,可以判断任意数据类型。
  • 优点:通用且精确,适用于所有数据类型的判断。缺点:语法稍显复杂,需要使用较长的表达式。
console.log(Object.prototype.toString.call("Hello"));  // "[object String]"
console.log(Object.prototype.toString.call(50));       // "[object Number]"
console.log(Object.prototype.toString.call(true));     // "[object Boolean]"
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]

5.使用constructor

  • 在定义一个函数(构造函数)的时候,JS引擎会为其添加prototype原型,原型上有其对应的constructor属性指向该构造函数,从而原型和构造函数之间互相知道对方。当构造函数实例化的时候,会产生对应的实例,其实例可以访问对应原型上的constructor属性,这样该实例就可以了解到通过谁产生了自己,这样就可以在新对象产生之后了解其数据类型。
  • constructor方法虽然该方法可以判断其数据类型,但存在两个缺点:1.nullundefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。2.函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
const val1 = 1; 
console.log(val1.constructor); // [Function: Number] 
const val2 = 'abc'; 
、uctor); // [Function: String] 
const val3 = true; 
console.log(val3.constructor); // [Function: Boolean] 

四、类型转换

分为两类:隐式类型转换显式类型转换

1.显示类型转型

显示类型转换是开发人员手动执行的类型转换操作,通过一些内置函数或操作符实现。在强制类型转换中,开发人员明确地指定要将值转换为的目标类型。常见的强制类型转换方式包括:

  • 使用 Number()parseInt(value) 或 parseFloat(value)函数将值转换为数字类型。
  • 使用 String() 函数将值转换为字符串类型。
  • 使用 Boolean() 函数将值转换为布尔类型。
let num = "123";
let str = String(num); // "123"
let int = Number(str); // 123
let bool = Boolean(int); // true

console.log(typeof str); // string
console.log(typeof int); // number
console.log(typeof bool); // boolean

2.显示类型转换

这是 JavaScript 自动执行的类型转换,通常发生在表达式中,当运算符或方法需要不同类型的参数时。例如

  • 加法运算符(+):用于将数字、字符串和其他类型相加时进行隐式类型转换。
  • 比较运算符(==!=):在使用相等和不相等运算符时,JavaScript 会根据需要自动进行类型转换,比较两个值是否相等。
  • 逻辑运算符(&&||):逻辑与(&&)和逻辑或(||)也可以进行隐式类型转换,将操作数转换为布尔值并返回原始值。
  • 三元条件运算符(?:):用于条件判断时,也会触发隐式类型转换以满足条件表达式的要求。
//  字符串与数字相加:
const result = "10" + 5;
// 在这里,数字 5 被隐式转换为字符串 "5",然后与字符串 "10" 进行拼接,结果为字符串 "105"

// 数字和布尔值的运算:
const result1 = 10 - true;
// 在这里,布尔值 true 被转换为数字 1,然后与数字 10 进行减法运算,结果为数字 9

// 逻辑运算中的隐式类型转换:
Codeif (2) {
    // 2 被隐式转换为 true
}

// 比较运算中的隐式类型转换:
const isEqual = "10" == 10;
// 在比较时,字符串 "10" 被隐式转换为数字 10,然后进行比较