javascript中有哪些栈

发布时间:2022-07-01 13:48:33 作者:iii
来源:亿速云 阅读:165

JavaScript中有哪些栈

在JavaScript中,栈(Stack)是一种常见的数据结构,遵循“后进先出”(LIFO, Last In First Out)的原则。栈在JavaScript中的应用非常广泛,从函数调用栈到浏览器的历史记录管理,都可以看到栈的身影。本文将介绍JavaScript中常见的几种栈及其应用场景。

1. 函数调用栈(Call Stack)

函数调用栈是JavaScript引擎用来管理函数调用和返回的一种栈结构。每当一个函数被调用时,JavaScript引擎会将该函数的执行上下文(Execution Context)压入调用栈中。当函数执行完毕后,其执行上下文会从栈中弹出,控制权返回到调用该函数的位置。

function foo() {
    console.log('foo');
    bar();
}

function bar() {
    console.log('bar');
}

foo();

在上面的代码中,foo函数调用时,foo的执行上下文被压入调用栈。接着,foo函数内部调用了bar函数,bar的执行上下文也被压入调用栈。当bar执行完毕后,其执行上下文从栈中弹出,控制权返回到foo。最后,foo执行完毕后,其执行上下文也从栈中弹出。

2. 浏览器的历史记录栈(History Stack)

浏览器的历史记录栈用于管理用户在浏览器中访问的页面历史。每当用户访问一个新页面时,该页面的URL会被压入历史记录栈中。用户点击“后退”按钮时,浏览器会从栈中弹出最近访问的URL,并加载对应的页面。

// 假设用户依次访问了以下页面
history.pushState({}, '', '/page1');
history.pushState({}, '', '/page2');
history.pushState({}, '', '/page3');

// 用户点击“后退”按钮
history.back(); // 返回到/page2
history.back(); // 返回到/page1

3. 手动实现的栈数据结构

虽然JavaScript本身没有内置的栈数据结构,但我们可以使用数组来手动实现一个栈。数组的pushpop方法正好符合栈的“后进先出”原则。

class Stack {
    constructor() {
        this.items = [];
    }

    push(element) {
        this.items.push(element);
    }

    pop() {
        if (this.items.length === 0) {
            return "Underflow";
        }
        return this.items.pop();
    }

    peek() {
        return this.items[this.items.length - 1];
    }

    isEmpty() {
        return this.items.length === 0;
    }

    size() {
        return this.items.length;
    }
}

const stack = new Stack();
stack.push(10);
stack.push(20);
stack.push(30);
console.log(stack.pop()); // 输出 30
console.log(stack.peek()); // 输出 20

4. 递归调用栈

递归是函数调用自身的一种编程技巧。在递归调用中,每次函数调用都会将当前的执行上下文压入调用栈中。如果递归深度过大,可能会导致栈溢出(Stack Overflow)错误。

function factorial(n) {
    if (n === 0) {
        return 1;
    }
    return n * factorial(n - 1);
}

console.log(factorial(5)); // 输出 120

在上面的代码中,factorial函数递归调用自身,每次调用都会将当前的执行上下文压入调用栈中。当递归深度过大时,可能会导致栈溢出。

5. 事件循环中的任务栈(Task Queue)

在JavaScript的事件循环机制中,任务栈(Task Queue)用于管理异步任务的执行顺序。任务栈中的任务按照“先进先出”(FIFO, First In First Out)的原则执行。常见的异步任务包括setTimeoutsetIntervalPromise等。

setTimeout(() => {
    console.log('Timeout 1');
}, 0);

Promise.resolve().then(() => {
    console.log('Promise 1');
});

console.log('Sync');

在上面的代码中,setTimeoutPromise的回调函数会被放入任务栈中。事件循环会先执行同步代码,然后从任务栈中取出任务执行。因此,输出顺序为:

Sync
Promise 1
Timeout 1

总结

JavaScript中的栈结构在多个场景中都有应用,包括函数调用栈、浏览器的历史记录栈、手动实现的栈数据结构、递归调用栈以及事件循环中的任务栈。理解这些栈的工作原理和应用场景,有助于我们更好地掌握JavaScript的编程技巧和性能优化。

推荐阅读:
  1. JavaScript全栈开发
  2. Python中有哪些实现栈的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

javascript

上一篇:javascript属于html5吗

下一篇:PHP有哪些面试题及答案

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》