Make writing a habit together! This is the sixth day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

Hello, I’m Yang Chenggong.

In the previous two articles we learned about stacks and implemented them with arrays and objects, respectively. That was the last in the stack series, which focused on doing some more internal optimizations and using the stack to solve a base conversion problem.

Protect internal properties

In the last article we implemented an object to simulate the operation of the stack, but one of the indiscreet aspects is that the internal variables count and items can be accessed externally, which is not what we want.

Count and items are essentially private variables. Private variables are meant for internal logical use and are not externally accessible. But JavaScript does not yet provide syntax for “private variables.” What about that?

In fact, there are methods, and here are some.

Underline naming convention

If you’ve looked at the source code for many JavaScript projects, you’ve probably seen variables starting with _. This is a developer convention, not a standard. Developers use this naming to indicate that the variable is private.

According to this convention, our name above should look like this:

this._count = 0
this._items = {}
Copy the code

But in fact you can access _count externally, so it’s a convention, just to indicate that this variable is a private variable.

Closure in conjunction

You’re familiar with closures: variables are accessible internally, but not externally. Isn’t that what we need?

After reciting the closure interview questions for so long, it finally came in handy. Let’s modify the Stack class with closures:

const Stack = (() = > {
  let _count;
  let _items;
  
  class Stack {
    constructor() {
      _count = 0;
      _items = {};
    }
    push(value) { 
      _items[_count] = value;
      _count++;
    } 
    pop() { 
      if(this.isEmpty()) { 
        return undefined; 
      } 
      _count--
      let item = _items[_count]
      delete _items[_count]
      return item
    }
    size() {
      return _count;
    }
    toString() {
      let arr = Object.values(_items);
      return arr.toString();
    }
    isEmpty() {
      return _count === 0;
    }
    peek() {
      if(this.isEmpty()) {
        return undefined;
      }
      return _items[_count - 1]}clear() {
      _count = 0; _items = {}; }}return Stack
})()
Copy the code

Execute the function immediately, define a private variable within the function, and return the class.

If you are not familiar with the exact logic of the Stack class, please refer to the previous article on JavaScript data structures in Anger – Stack (2).

Now let’s try it out:

var stack = new Stack();

/ / into the stack
stack.push("Beijing");
stack.push("Shanghai");
console.log(stack.toString()); // 'Beijing, Shanghai'
console.log(stack.size()); / / 2

/ / out of the stack
console.log(stack.pop()); // 'Shanghai'
console.log(stack.toString()); // 'Beijing'
Copy the code

The class code logic is exactly the same as above, except that this.count is replaced by _count, so that the variables can be accessed by code inside the function scope, but not by code outside the function scope, thus implementing the effect of private variables.

Implement base conversion with stack

Above we implemented a fairly complete stack using closure +class. In fact, there are many application scenarios of stack, for example, we are going to introduce this one, how to use stack to achieve base conversion?

Let’s look at how decimal is converted to binary (binary is full binary). The usual method is to divide a decimal number by 2 and round the quotient, recording the remainder; If the quotient is not 0, continue to divide by 2, mod, until the result is 0.

For example, converting the decimal number 10 to a binary number would look something like this:

10 / 2 = 5More than,0;
5 / 2 = 2More than,1;
2 / 2 = 1More than,0;
1 / 2 = 0More than,1;
Copy the code

And then after each mod, we push the remainder onto the stack, and we end up with something like this:

[0.1.0.1]
Copy the code

After all the remainder is on the stack, all the remainder is off the stack, and finally the output is concatenated to 1010, which is the corresponding binary value.

Ok, we have the idea, let’s look at the code implementation:

const toBinary = number= > {
  // Stack instance
  let stack = new Stack()
  / /,
  let value = number
  / / remainder
  let rem
  let string = ' '

  while (value > 0) {
    rem = value % 2;
    stack.push(rem)
    value = Math.floor(value / 2)}while(! stack.isEmpty()) { string += stack.pop() }return Number(string)
}
Copy the code

First, the argument to the function is a decimal integer. Then with the quotient greater than 0 as the condition of the loop, the implementation of the stack operation, and finally the loop out of the stack, splicing characters, to get the binary value.

Let’s test it out:

console.log(toBinary(10)) / / 1010
console.log(toBinary(16)) / / 10000
console.log(toBinary(28)) / / 11100
Copy the code

Good luck with the right result!

Stack the subtotal

Stack is a very common data structure, we first introduced its concept and characteristics, and then used the array and object respectively to achieve a custom stack, and finally use the stack to achieve the base conversion. I believe that after these three chapters, you already understand what a stack is.

In the next article, we’ll start looking at the third data structure: queues.

Join a study group

This article source public number: programmer success. This is the fifth chapter of learning JavaScript data structure and algorithm, this series will be updated for a month, welcome to pay attention to the public account, click “add group” to join our learning team ~