TypeScript数组与对象实现栈的性能对比详解
本文深入解析TypeScript中栈数据结构的两种实现方式:数组与对象。通过对比分析入栈、出栈等操作的时间复杂度,揭示数组O(n)与对象O(1)的性能差异。文章提供完整的TypeScript代码示例及十进制转二进制测试案例,帮助开发者根据实际场景选择最优实现方案。
前言
栈是一种常用的数据结构,适用于需要频繁访问最新存入数据的场景。当业务逻辑要求优先处理最近添加的元素时,栈结构是理想选择。
在TypeScript中,栈主要有两种实现路径:基于数组和基于对象。尽管两者最终提供的功能一致,但在运行性能和资源消耗上存在显著差异。
本文将详细剖析这两种实现方式在性能表现上的具体区别,并提供完整的TypeScript代码实现,供开发者参考与实践。
数组实现栈
本文聚焦于栈的代码实现细节。若读者对栈的基本概念尚不熟悉,建议先阅读相关基础文章以建立完整认知。
实现思路
栈的核心特性是后进先出(LIFO)。利用数组的有序性,可以自然地映射栈的结构与行为。
一个完整的栈实现通常包含以下核心功能:
- 入栈操作:将新元素添加至栈顶,即数组末尾。
- 出栈操作:移除栈顶元素,并返回该元素的值。
- 获取栈顶元素:不改变栈状态,直接返回当前栈顶元素的值。
- 判断栈是否为空:检查数组中是否包含任何元素。
- 清空栈:移除栈内所有现有元素,重置栈状态。
- 获取栈大小:返回当前栈中存储的元素总数。
- 输出栈内数据:将栈中所有元素转换为字符串形式返回,便于查看或调试。
分析上述功能需求,JavaScript数组原生提供了丰富的API,可以高效地实现这些栈操作。以下是各功能的具体实现策略。
- 入栈(push):直接调用数组的push方法,将元素追加到数组末尾。
- 出栈(pop):直接调用数组的pop方法,移除并返回数组最后一个元素。
- 获取栈顶元素(peek):通过访问数组长度减1的索引,获取最后一个元素。
- 判断栈是否为空(isEmpty):检查数组长度是否等于0。
- 清空栈(clear):将数组引用重新赋值为空数组,或循环调用pop方法直至数组为空。
- 获取栈大小(size):直接返回数组的length属性值。
- 输出栈内数据:调用数组的toString方法,将数组内容转换为逗号分隔的字符串。
实现代码
明确实现逻辑后,即可将上述思路转化为具体的TypeScript代码。
- 新建一个Stack.ts文件
- 定义栈类并规定其泛型类型
private items: any[];
- 在构造器中初始化栈内部存储数组
constructor() {
this.items = [];
}
- 根据前述思路实现栈的各项操作方法
// 入栈
push(item:any) {
this.items.push(item);
}
// 出栈
pop() {
return this.items.pop();
}
// 返回栈顶元素
peek() {
return this.items[this.items.length - 1];
}
// 判断栈是否为空
isEmpty() {
return this.items.length === 0;
}
// 清空栈栈内元素
clear() {
this.items = [];
}
// 获取栈内元素数量
size():number{
return this.items.length;
}
// 将栈内元素转为字符串
toString(){
return this.items.toString();
}
完整代码请移步:Stack.ts
编写测试代码
完成栈类实现后,需通过测试用例验证各方法是否按预期工作。
- 新建一个StackTest.js文件
- 实例化一个栈对象
const stack = new Stack();
- 测试栈内方法是否正确执行
// 入栈
stack.push("第一条数据");
stack.push("第二条数据");
// 出栈
stack.pop();
// 返回栈顶元素
console.log(stack.peek());
// 查看栈大小
console.log(stack.size());
// 判断栈是否为空
console.log(stack.isEmpty());
// 返回栈内所有元素
console.log(stack.toString())
// 清空栈
stack.clear()
完整代码请移步:StackTest.js
执行结果如下

对象实现栈
虽然数组是存储栈元素的最直观方式,但在处理海量数据时,需评估操作效率。
使用数组时,多数操作的时间复杂度为O(n),因为可能需要遍历整个数组来定位目标。在最坏情况下,需访问数组的每个位置。此外,数组作为有序集合,为维持顺序可能占用额外内存空间。
若能直接访问元素,减少内存占用,同时保持元素有序排列,则是更优的解决方案。
实现代码
可以使用对象来存储栈元素,利用对象的键值对特性保持顺序并遵循LIFO原则。以下是对象实现栈的具体方法。
- 新建一个ObjStack.ts文件
- 定义栈对象的结构接口
interface StackObj {
[propName: number] : any;
}
- 定义栈类并规定其类型,使用count变量记录栈的大小。
private items: StackObj;
private count: number;
- 在构造器中初始化栈相关变量
this.items = {};
this.count = 0;
- 入栈:将当前栈的大小作为新元素的键(key)。
push(item: any) {
this.items[this.count] = item;
this.count++;
}
- 出栈:将栈大小减1,获取栈顶元素,删除该元素,并返回栈顶元素。
pop() {
if(this.isEmpty()){
return undefined;
}
this.count--;
const result = this.items[this.count];
delete this.items[this.count];
console.log(this.items);
return result;
}
- 返回栈顶元素:以当前栈大小减1为键,获取对应的值。
peek() {
if(this.isEmpty()){
return undefined;
}
return this.items[this.count - 1];
}
- 判断栈是否为空:检查栈内元素数量,清空栈内元素。
// 判断栈是否为空
isEmpty() {
return this.count === 0;
}
// 清空栈内元素
clear() {
this.items = [];
this.count = 0;
}
// 获取栈内元素数量
size():number{
return this.count;
}
- 将栈内元素转为字符串:遍历当前栈对象中的数据,将栈中的数据用逗号拼接并返回。
toString(){
if (this.isEmpty()){
return "";
}
let objString = `${this.items[0]}`;
for (let i = 1; i < this.count; i++){
objString = `${objString},${this.items[i]}`
}
return objString;
}
完整代码请移步:ObjStack.ts
编写测试代码
使用对象实现的栈完成后,需添加测试数据以验证方法执行的准确性。
- 新建一个StackObjTest.js文件
- 实例化一个栈
const stack = new ObjStack();
- 测试栈内方法是否正确执行
// 入栈
stack.push("第一条数据");
stack.push("第二条数据");
// 出栈
stack.pop();
// 返回栈顶元素
console.log(stack.peek());
// 查看栈大小
console.log(stack.size());
// 判断栈是否为空
console.log(stack.isEmpty());
// 返回栈内所有元素
console.log(stack.toString())
// 清空栈
stack.clear()
完整代码请移步:StackObjTest.js
执行结果如下

二者的区别
数组大部分方法的时间复杂度都为O(n),数组中的元素是一个有序集合,为了保证元素排列有序,它会占用更多的内存空间。
对象可以通过key直接访问到目标元素时间复杂度为O(1),我们可以直接目标元素进行操作,速度明显比数组快了很多倍。
接下来,我们通过一个实例来看看这两者在执行速度上的差异。
十进制转二进制
把十进制转为二进制,需要将该十进制除以2并对商取整,直到结果是0为止。
- 声明一个函数参数为一个十进制数
const decimalToBinaryStack = function (decNumber) {
}
- 函数内部声明一个变量,用于接收当前传进来的参数进行除法运算后得到的值。
// 传进来的十进制数
let number = decNumber;
- 函数内部实例化一个栈,用于保存模运算后得出的值。
- 函数内部声明两个变量,用户保存当前模运算的值和最终生成的二进制字符串
// 余数
let rem;
// 二进制结果
let binaryString = "";
- while循环,判断当前参数进行除法运算后得到的值是否为0,如果不为0就对当前结果进行模运算,将模运算得到的值入栈,对当前结果进行除法运算,直至当前结果为0。
while (number > 0) {
// 模运算
rem = Math.floor(number % 2);
// 将余数入栈
stack.push(rem);
// 当前十进制结果除以二
number = Math.floor(number / 2);
}
- while循环,将栈中的数据取出拼接到二进制结果字符串中去
while (!stack.isEmpty()) {
binaryString += stack.pop().toString();
}
- 返回二进制结果字符串
return binaryString;
完整代码请移步:Examples.js
实现代码如上所述,唯一不同的就是一个使用的是对象栈一个使用的数组栈,接下来我们来看下不同栈的运行时间差距。

以上就是TypeScript数组实现栈与对象实现栈的区别详解的详细内容,更多关于TypeScript数组对象实现栈的资料请关注本站其它相关文章!
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58








