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

栈用在编译器和内存中保存变量、方法调用。

栈的方法

  • push(element) 添加元素到栈顶
  • pop() 移除栈顶元素,返回被移除元素
  • peek() 返回栈顶元素
  • isEmpty() 是否空栈
  • clear() 移除栈中所有元素
  • size() 返回栈的元素个数

    实现

    基于数组实现

    1. class Stack {
    2. constructor() {
    3. this.items = [];
    4. }
    5. push(element) {
    6. this.items.push(element);
    7. }
    8. pop() {
    9. return this.items.pop();
    10. }
    11. peek() {
    12. return this.items[this.items.length - 1];
    13. }
    14. isEmpty() {
    15. return this.items.length === 0;
    16. }
    17. clear() {
    18. this.items = [];
    19. }
    20. size() {
    21. return this.items.length;
    22. }
    23. toString() {
    24. return this.items.toString();
    25. }
    26. }

    基于对象实现

    1. class Stack {
    2. constructor() {
    3. this._count = 0;
    4. this._items = {};
    5. }
    6. push(element) {
    7. this._items[this._count] = element;
    8. this._count++;
    9. }
    10. pop() {
    11. if (this.isEmpty()) {
    12. return undefined;
    13. }
    14. this._count--;
    15. const result = this._items[this._count];
    16. delete this._items[this._count];
    17. return result;
    18. }
    19. peek() {
    20. if (this.isEmpty()) {
    21. return undefined;
    22. }
    23. return this._items[this._count - 1];
    24. }
    25. isEmpty() {
    26. return this._count === 0;
    27. }
    28. clear() {
    29. this._items = {};
    30. this._count = 0;
    31. }
    32. size() {
    33. return this._count;
    34. }
    35. toString() {
    36. if (this.isEmpty()) {
    37. return '';
    38. }
    39. let objString = `${this._items[0]}`;
    40. for (let i = 1; i < this._count; i++) {
    41. objString = `${objString}, ${this._items[i]}`;
    42. }
    43. return objString;
    44. }
    45. }

    私有成员

    使 _ 真正不能访问

  1. Symbol ,使用 Object.getOwnPropertySymbols() 可被破
  2. WeakMap

    1. const Stack = (function () {
    2. const _items = new WeakMap();
    3. return class Stack{
    4. constructor() {
    5. _items.set(this, []);
    6. }
    7. push(element) {
    8. _items.get(this).push(element);
    9. }
    10. pop() {
    11. return _items.get(this).pop();
    12. }
    13. peek() {
    14. return _items.get(this)[_items.get(this).length - 1];
    15. }
    16. isEmpty() {
    17. return _items.get(this).length === 0;
    18. }
    19. clear() {
    20. _items.get(this) = [];
    21. }
    22. size() {
    23. return _items.get(this).length;
    24. }
    25. toString() {
    26. return _items.get(this).toString();
    27. }
    28. }
    29. })();