栈是一种数据结构,与数组相比,它有更多的限制。
我们只能通过将项目添加到堆栈的顶部来增加它们。而且我们只能删除堆栈顶部的项目。
想想看,它就像一堆书。你只能在上面添加书,你也只能删除上面的书。
因此,如果你添加了一堆书,然后你想访问你添加的第一本书,你首先需要移除所有的书,直到你到达你添加的那本书。
这个概念被称为先入后出(FILO)。
虽然JavaScript中的数组是内置的,我们不需要建立它们,但我们必须实现堆栈。
我们要创建一个数据结构来封装我们的数据,使其无法从外部访问,我们只允许push() 方法向堆栈中添加数据,而pop() 方法从堆栈中删除数据。
我们可以通过许多不同的方式来实现这一点。一种方法是使用类,特别是我将使用私有类字段。私有类字段还不是JavaScript标准的一部分,但它们在Chrome、Edge、Safari和Node.js的第12版中是可用的。在Firefox中仍然不可用,希望很快就能实现。
我为什么要使用它们?因为它们允许我们非常容易地封装类的内部状态,并从外部保护它。
class Stack {
#items = []
push = (element) => this.#items.push(element)
pop = () => this.#items.pop()
isempty = () => this.#items.length === 0
empty = () => (this.#items.length = 0)
size = () => this.#items.length
}
我们有5个公共方法:push 和pop 来添加/删除堆栈,isempty 来检查堆栈是否为空,empty 来清空堆栈,size 来获得堆栈大小。
我们现在可以从该类中创建一个堆栈对象,并对其进行操作。
const stack = new Stack()
stack.push(1)
stack.push(2)
stack.push(3)
console.log(stack.size()) //3
console.log(stack.pop()) //[ 3 ]
console.log(stack.size()) //2
一切都会以同样的方式在公共属性下工作。
class Stack {
items = []
push = (element) => this.items.push(element)
pop = () => this.items.pop()
isempty = () => this.items.length === 0
empty = () => (this.items.length = 0)
size = () => this.items.length
}
除了现在我们可以从外部检查items 。
const stack = new Stack()
stack.push(2)
console.log(stack.items) //[ 2 ]
而对于私有类属性,访问stack.items 将返回undefined 。