欢迎光临
我们一直在努力

搞懂JS数据类型?8大类型拆解+内存底层+避坑实战

一、为什么你总踩JS数据类型的坑?

你是不是也遇到过:

  • 0.1 + 0.2 不等于 0.3?
  • 改了obj2,obj1也莫名变了?
  • 分不清null和undefined,面试被追问到哑口?

这篇文章帮你彻底搞懂JS的8种数据类型,从底层内存逻辑到实战避坑,全是干货,看完就能用,再也不踩数据类型的坑!
在这里插入图片描述

二、JS数据类型总览:8种类型分类

根据ECMA262规范,JS一共有8种数据类型,分为两大阵营:

2.1 原始数据类型(7种)

也叫简单数据类型,内存空间固定,赋值时是拷贝式赋值:

  • Number:普通数值
  • String:字符串
  • Boolean:布尔值
  • null:空值(有意设置的空对象引用)
  • undefined:未定义(变量未初始化/属性不存在等)
  • Symbol(ES6新增):唯一标识符
  • BigInt(ES6新增):处理超大数值

2.2 引用数据类型(1种)

  • Object:对象(包括数组、函数等),内存空间不固定,赋值时是引用式赋值

三、逐个拆解:每种类型的实战用法+踩坑点

3.1 Number:小心小数精度问题

JS用二进制存储数值,导致小数计算不精确,这是高频踩坑点!

实战代码:

let a = 0.1
let b = 0.2
console.log(a + b) // 输出:0.30000000000000004,不是0.3!

踩坑提醒:

  • 金融计算、精度要求高的场景,不要直接用Number做小数运算
  • 解决方案:转成整数计算后再转回,或用专门的精度处理库

3.2 null:主动清空值,释放内存

null是「有意设置为空」,核心用途是清空变量、释放内存。

实战代码:

// 定义一个占用大量内存的对象
let largeObject = {
data: new Array(10000000).fill("test")
}
// 手动释放内存:将引用置为null,垃圾回收会清理
largeObject = null
console.log(largeObject) // 输出:null

在这里插入图片描述

踩坑提醒:

  • null不是「未定义」,是「主动置空」,和undefined本质不同
  • typeof null 会返回 “object”,这是JS的历史bug,记住即可

3.3 undefined:默认未初始化状态

undefined表示「本该有值,但目前没有」,常见场景:

实战代码:

// 1. 变量声明未赋值
let a
console.log(a) // 输出:undefined

// 2. 对象不存在的属性
let obj = {}
console.log(obj.age) // 输出:undefined

// 3. 函数无返回值
function noReturn() {}
console.log(noReturn()) // 输出:undefined

// 4. 访问不存在的数组索引
let arr = [1, 2, 3]
console.log(arr[3]) // 输出:undefined

踩坑提醒:

  • 不要手动给变量赋值undefined,空值用null更语义化
  • 判断变量是否初始化,用 a === undefined 更准确

3.4 Symbol:保证标识符唯一

Symbol是ES6新增,每个Symbol值都是唯一的,解决「属性名冲突」问题。

实战代码:

// 即使标签相同,Symbol也不相等
console.log(Symbol('张三') === Symbol('张三')) // 输出:false
console.log(typeof Symbol('张三')) // 输出:symbol

// 作为对象唯一属性名
let obj = {
[Symbol()]: '唯一值',
prop: '普通属性'
}
console.log(Object.keys(obj)) // 输出:['prop'],Symbol属性不会被常规遍历获取

踩坑提醒:

  • Symbol不能用new创建(是原始类型,不是对象)
  • Symbol属性不会被for…in、Object.keys遍历,需用Object.getOwnPropertySymbols获取

3.5 BigInt:处理超大数值

Number有取值范围(±2^53-1),超过后精度丢失,BigInt专门解决这个问题。

实战代码:

// 超大整数,加n表示BigInt类型
let num1 = 99999999999999999999999999999999999999999999999999n
let num2 = 123456789098765433467324577654789008733233456899003466788924243n

console.log(num1 + num2) // 正确计算超大数相加
console.log(typeof num1) // 输出:bigint

// 踩坑点:BigInt只能和BigInt运算
console.log(num1 + 1n) // 正确,输出:100000000000000000000000000000000000000000000000000n
// console.log(num1 + 1) // 报错:Cannot mix BigInt and other types

踩坑提醒:

  • BigInt和Number不能混合运算,必须统一类型
  • BigInt不能用于Math对象的方法(如Math.max)

3.6 Object:引用赋值的坑

对象是引用类型,赋值时复制的是「内存地址」,不是值本身,这是新手高频踩坑点!

实战代码:

let obj = {name: "Alice"}
let obj2 = obj // 复制的是地址,不是新对象
obj2.company = "快手" // 修改obj2,obj也会变

console.log(obj) // 输出:{name: 'Alice', company: '快手'}
console.log(obj2) // 输出:{name: 'Alice', company: '快手'}

// 对比原始类型的拷贝赋值
let a = null
let b = a
b = 2
console.log(a, b) // 输出:null 2,a不受b影响

踩坑提醒:

  • 想复制对象但不共享引用,需用浅拷贝(Object.assign/解构)或深拷贝(JSON.parse(JSON.stringify())/专门库)
  • 函数参数传对象时,修改参数会影响原对象,注意副作用

四、内存视角:为什么原始类型和引用类型不一样?

理解内存分配,就能彻底搞懂两种类型的差异:

  • 栈内存:存储原始类型

    • 空间小、速度快
    • 变量直接存值,赋值时拷贝值
    • 函数执行完,栈内存会被快速释放
  • 堆内存:存储引用类型

    • 空间大、速度稍慢
    • 变量存的是「堆内存地址」,赋值时拷贝地址
    • 垃圾回收机制会清理无引用的堆内存(如把对象置为null)
  • 五、总结:核心要点速记

  • JS共8种数据类型:7种原始类型(Number/String/Boolean/null/undefined/Symbol/BigInt)+1种引用类型(Object)
  • 原始类型:拷贝赋值,栈内存存储,空间固定
  • 引用类型:引用赋值,堆内存存储,空间不固定
  • 避坑重点:Number小数精度、Object引用赋值、null/undefined区分、BigInt类型匹配
  • 赞(0)
    未经允许不得转载:171主机测评 » 搞懂JS数据类型?8大类型拆解+内存底层+避坑实战
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址