什么是js执行栈?

83 阅读3分钟

定义:栈是一种遵从后进先出原则的有序集合。新添加或者待删除的元素都保存在栈的同一段,称作栈顶,另一端就叫栈底,新的元素都靠近栈顶,旧的元素都接近栈底

创建一个基于数组的栈

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

向栈中添加数组

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

该方法只添加元素到栈顶,也就是栈的末尾。

从栈中移除元素

class Stack {
    constructor() {
        this.items = []
    }
    
    push (e) {
        this.items.push(e)
    }
    pop () {
        return this.items.pop
    }
}

查看栈顶的元素

class Stack {
    constructor() {
        this.items = []
    }
    
    push (e) {
        this.items.push(e)
    }
    pop () {
        return this.items.pop
    }
    peek() {
        return this.items[this.items.length - 1]
    }
}

因为类的内部是用数组保存元素的,所以访问数组的最后一个元素可以用length-1

检查元素是否为空

class Stack {
    constructor() {
        this.items = []
    }
    
    push (e) {
        this.items.push(e)
    }
    pop () {
        return this.items.pop
    }
    peek () {
        return this.items[this.items.length - 1]
    }
    isEmpty () {
        return this.items.length == 0
    }
}

清空栈元素

class Stack {
    constructor() {
        this.items = []
    }
    
    push (e) {
        this.items.push(e)
    }
    pop () {
        return this.items.pop
    }
    peek () {
        return this.items[this.items.length - 1]
    }
    isEmpty () {
        return this.items.length == 0
    }
    clear () {
        this.items = []
    }
    size () {
        return this.items.length
    }
}

一个栈就完成了

使用stack类

const stack = new Stack()
stack.push(5)
stack.pop()
stack.isEmpty ()

stack的优化,创建一个基于JavaScript对象的stack类

创建一个stack类最简单的方式是使用一个数组来存储其元素,在处理大量数据的时候,我们同样需要评估如何操作数据是最高效的。在使用数组的时候,大部分方法的时间复杂度底O(n).意思是,我们需要迭代整个数组知道找到要找的那个元素,在最坏的情况下需要迭代数组的所有位置,其中的N代表数组的长度,如果数组有更多元素的话,所需要的时间会更长,另外,数组是元素的一个有序的集合,为了保证元素排列有序,它会占用更多的内存空间

如果我们在处理大量数据的时候,可以直接获取元素,占用较少的内存空间,并且仍然保证所有元素按照我们的需要排列,我们可以使用一个JavaScript对象来存储所有的栈元素,保证他们的顺序并且遵循LIFO原则(后进先出)

声明一个类

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

 我们可以用count属性来帮助我们记录栈的大小(也可以帮助我们删除和添加元素)
 

向栈中插入元素 push

class Stack {
    constructor () {
        this.count = 0
        this.items = {}
    }
    push (e) {
        this.items[this.count] = e
        this.count ++
    }
}

验证一个栈是否为空和它的大小

class Stack {
    constructor () {
        this.count = 0
        this.items = {}
    }
    push (e) {
        this.items[this.count] = e
        this.count ++
    }
    rezie () {
        return this.count
    }
    isEmpty () {
        return this.count == 0
    }
}

从栈中弹出元素

由于我们没有使用数组来存储元素,需要手动实现移除元素的逻辑,pop方法同样返回了从栈中移除的元素

class Stack {
    constructor () {
        this.count = 0
        this.items = {}
    }
    push (e) {
        this.items[this.count] = e
        this.count ++
    }
    rezie () {
        return this.count
    }
    isEmpty () {
        return this.count == 0
    }
    pop () {
        if (isEmpty) return null
        const res = this.items[this.count]
        delete this.items()
        return res
    }
}

查看栈顶的值并将栈清空

class Stack {
    constructor () {
        this.count = 0
        this.items = {}
    }
    push (e) {
        this.items[this.count] = e
        this.count ++
    }
    rezie () {
        return this.count
    }
    isEmpty () {
        return this.count == 0
    }
    pop () {
        if (isEmpty) return null
        const res = this.items[this.count]
        delete this.items()
        return res
    }
    peek () {
        if (isEmpty) return null
        return this.items[this.count - 1]
    }
    clear () {
        this.items = {}
        this.count = 0
    }
}

实现一个toString

模拟数组的方法来实现一个toString

class Stack {
    constructor () {
        this.count = 0
        this.items = {}
    }
    push (e) {
        this.items[this.count] = e
        this.count ++
    }
    rezie () {
        return this.count
    }
    isEmpty () {
        return this.count == 0
    }
    pop () {
        if (isEmpty) return null
        const res = this.items[this.count]
        delete this.items()
        return res
    }
    peek () {
        if (isEmpty) return null
        return this.items[this.count - 1]
    }
    clear () {
        this.items = {}
        this.count = 0
    }
    toString() {
        let objString = this.item[0] + ''
        Object.values(this.items).foreEach(item => {
            objString = `${objString}, item`
        })
        return objString
    }
}

注意: 在创建别的开发者也可使用的数据结构或对象时,我们希望保护内部的元素,只有我们露出的方法才能修改使用。对于stack类来说,要确保元素只会被添加到栈,而不是栈底或者其他任意位置。所有有了一种约定,在开发时,会去预定以下划线开头的方法或者属性是不能私自使用