JavaScript 数据类型 两大分类
基本类型(Primitive Types) :
string:字符串
number:数字
boolean:布尔值
null:空值
undefined:未定义
symbol(ES6新增):符号,表示唯一值
bigint(ES2020新增):大整数,表示任意大的整数
引用类型(Reference Types) :
Object:对象
包括:Array, Function, Date, RegExp, Map, Set, WeakMap, WeakSet等。
基本类型 vs 引用类型的核心区别
特性
基本类型
引用类型
存储方式
栈内存(直接存储值)
堆内存(存储地址,栈中存指针)
赋值行为
复制值(新旧变量互不影响)
复制指针(指向同一内存对象)
比较方式
值比较('a' === 'a' → true)
引用比较({} === {} → false)
函数传参
传递值的副本
传递指针副本(内部修改影响外部对象)
动态属性
不可添加属性
可动态添加/删除属性
内存管理
变量销毁时自动回收
需垃圾回收机制处理
复习一下数据结构: 1.栈(Stack) 逻辑结构:一种线性结构,遵循后进先出(LIFO) 原则,仅允许在表的一端(栈顶)进行插入(push)和删除(pop)操作。 物理实现:通常通过数组或链表实现,数据连续存储,操作仅涉及栈顶元素。 典型操作: push:将元素压入栈顶。 pop:弹出栈顶元素。 peek:查看栈顶元素(不弹出)。 2.堆(Heap) 逻辑结构:一种树形结构,通常为完全二叉树,满足堆性质(父节点的值大于或等于子节点的值称为最大堆,反之为最小堆)。 物理实现:通过数组实现,逻辑上模拟树结构,物理上连续存储。 典型操作: insert:插入元素并保持堆性质。 extract:移除根节点(最大或最小值)。 heapify:调整节点位置以维护堆性质。
示例说明 1 2 3 4 5 6 7 8 9 10 11 let num1 = 10 ;let num2 = num1; num2 = 20 ; console .log (num1); let obj1 = { count : 10 };let obj2 = obj1; obj2.count = 20 ; console .log (obj1.count );
Symbol 详解 作用 :创建唯一的、不可变的值,常用作对象属性的键(避免命名冲突)。特性 :
通过 Symbol([description]) 创建
即使描述相同,Symbol 值也不同:Symbol('id') !== Symbol('id')
不可枚举(for...in 跳过),需用 Object.getOwnPropertySymbols() 获取1 2 3 const sym1 = Symbol ('id' );const sym2 = Symbol ('id' );console .log (sym1 === sym2);
应用场景:
唯一对象属性键 避免第三方库属性名冲突:
1 2 3 4 const user = { name : "Alice" , [Symbol ('id' )]: 123 };
模拟私有属性 (需配合 Object.defineProperty 或闭包实现真正私有):
1 2 3 4 5 6 const _password = Symbol ('password' );class User { constructor (password ) { this [_password] = password; } }
全局 Symbol 注册表 跨模块共享 Symbol:
1 2 3 4 5 const id = Symbol .for ('global_id' );const sameId = Symbol .for ('global_id' );console .log (id === sameId);
内置 Symbol 值 定制对象行为(如迭代器):
1 2 3 4 5 6 7 const obj = { [Symbol .iterator ]: function * () { yield 1 ; yield 2 ; } }; console .log ([...obj]);
应用场景
场景
说明
示例
唯一对象属性键
由于Symbol值是唯一的,因此可以用来作为对象属性的键,避免属性名冲突
const obj = { [Symbol('id')]: 123 };
模拟私有属性
配合闭包实现伪私有属性(虽然ES6的类并没有真正的私有属性,但使用Symbol可以在一定程度上模拟私有属性,因为外部无法直接访问Symbol属性)
const _key = Symbol(); class Safe { constructor(k) { this[_key] = k; } }
全局Symbol注册表
跨模块/文件共享Symbol
//module1.js Symbol.for('global'); //module2.js Symbol.for('global');
内置Symbol行为定制
实现迭代协议等特殊行为(ES6提供了一些内置的Symbol值,用于改变语言内部行为,如Symbol.iterator(定义迭代器)、Symbol.toStringTag)
const iterable = { [Symbol.iterator]: function*() { yield 1; } };
定义常量
用于定义一组常量,保证这组常量的值都是不相等的。
const LOG_LEVEL = {DEBUG: Symbol('debug'),INFO: Symbol('info'),ERROR: Symbol('error')};
BigInt 详解 特性 作用 :表示任意精度的整数,解决 Number 类型无法安全表示的大整数问题(Number.MAX_SAFE_INTEGER = 2^53 - 1)。特性 :
字面量加 n 后缀:12345678901234567890n
通过 BigInt() 函数转换:BigInt("9007199254740993")
不能与 Number 直接运算(需显式转换)
应用场景:
大整数运算 金融、科学计算等需要高精度的场景:
1 2 3 const big1 = 9007199254740993n ;const big2 = 1n ;console .log (big1 + big2);
大 ID 处理 数据库返回的 64 位 ID(如 Snowflake 算法生成的 ID):
1 const id = BigInt ("12345678901234567890" );
高精度时间戳 纳秒级时间戳运算:
1 2 3 4 const start = process.hrtime .bigint (); const end = process.hrtime .bigint ();console .log (`耗时: ${(end - start) / 1000000n } 毫秒` );
大数加密/哈希 密码学中的大整数运算:
1 const prime = BigInt ("0xFFFFFFFFFFFFFFFFC90FDAA..." );
注意事项:
不支持 Math 对象的方法
与 Number 比较时类型不同(1n === 1 → false)
JSON 序列化 需自定义处理(默认抛出错误)
1 2 3 4 5 6 console .log (1n == 1 ); console .log (1n === 1 ); console .log (Math .sqrt (16n ));
总结对比
类型
核心特性
典型应用场景
Symbol
唯一性、不可枚举、避免冲突
对象元编程、私有属性模拟、库开发
BigInt
任意精度、突破Number安全限制
大整数ID、金融计算、高精度时间处理