1. Fibonacci numbers

Are you familiar with the Fibonacci sequence? And I’ll let you write it right away:

Function fib(n) {if(n < 2) return fib(n-1) + fib(n-2)}Copy the code

Some of your friends might think that if n is less than 0 you’re going to have a problem and you might add:

Function fib(n) {console.count(' console.count ') 13529 if(n < 0) return if(n < 2) return n return fib(n-1) + fib(n-2)} Function fib(n) {console.count(' total ') // total: 13529 if(n < 0) throw Error(' the input parameter must be greater than or equal to 0') if(n < 2) return n return fib(n-1) + fib(n-2)}Copy the code

That might be the end of it, but if that’s it, then if you pass 20, 30, or even 90, your computer dies on the spot, so it needs to be optimized not to do mindless calculations.

So we can give it further optimization, and then we have:

Var obj = {}, arr = [] function fib(n) {console.count(' console.count ') 39 if(n < 0) throw Error(' input parameter must be greater than or equal to 0') if(n < 2) return n if(obj. HasOwnProperty (n)) return obj[n] let num = fib(n-1) + fib (n - 2) arr. Push (num) / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - > have a need to display an array obj [n] = num return num} / / 6765 (20) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] console.log(fib(20), arr);Copy the code

Store values in obj, and then when you call fib(), check hasOwnProperty(n) to see if any of them have already been computed and stored in fib(). If so, grab them directly from fib(n) so that you don’t have to waste time and effort doing something already done. By doing this, I can significantly reduce the number of calculations, and the computer says I’m good again. But it doesn’t look elegant on the outside, but if you put it in, obj loses its power, so let’s try to make a recursive function inside fib and see if we can solve this problem.

For further optimization

Function fib(n) {let arr = [] if(n < 0) throw Error(' Pass parameter must be greater than or equal to 0') function computed(n, pre, Next) {console.count(' total ') // total: 21 arr.push(pre) if(n === 0) return pre return computed(n - 1, next, Let obj = {a: arr, b: computed(n, 0, 1)} return obj} // obj: {// a: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] // b: 6765 // } console.log(fib(20));Copy the code

By creating a recursive function inside the function, you don’t have to declare a variable to store values (arr=[] is used to display arrays). This also saves time traversing objects, which seems to improve performance a bit. Computed is n minus 1, smaller and smaller every time it’s called, and then it gives the pre the value of the last next; The value of Next adds the two pre and next together, so 0+1=1, 1+1=2.

If you have a better way, welcome to point out, let us progress together.

2. Convert the array [1,2,3,[4,5]] to the following format, and ensure that subsequent additions to the array are displayed in the following format

// In order to save space had to put like this, please forgive me! { children:[ { value:1 }, { value:2 }, { value:3 }, { children: [ { value:4 }, { value:5 } ] }, ] }Copy the code

Most people’s first thought when they see this is to loop through it with a for or a while loop and convert it to something like this.

Use a while loop

----- function Transition (arr) {var newArr = [] var index = 0 while (index < arr.length) {if(typeof arr[index] === 'number') { newArr.push({ value: arr[index] }) } else if(Array.isArray(arr[index])) { newArr.push({ children: [transition(arr[index])]})} index++} return newArr} console.log(transition([1,2,3,[4,5]]));Copy the code

Use the for loop

// ----- use for loop ----- function transition(arr) {var newArr = [] for(let I = 0; i<arr.length; i++) { if(typeof arr[i] === 'number') { newArr.push({ value: arr[i] }) } else if(Array.isArray(arr[i])) { newArr.push({ children: [transition(arr[I])]})}} return newArr} console.log(transition([1,2,3,[4,5]]));Copy the code

It’s true that you can add as much or as little as you want, but there’s a problem here. I’m sure you all know if it’s too many lines, 20 lines for the while and 18 lines for the for loop. How about using map?

Use map higher-order functions

// ----- ----- function Transition (arr) {return arr.map(I => {if(typeof I === 'number') {return{value: I}} else if(array.isarray (I)) {return {children: [transition(I)]}}} console.log(transition([1,2,3,[4,5]]));Copy the code

At 16 lines, it looks a lot cleaner than the previous two methods, and we all know that the map function also iterates through a group of numbers, but it hides the traversal from us to reduce the amount of code.

Let’s see if we can judge the array before we map it. Try to compress further

// ----- try to further compression ----- function Transition (arr) {if(typeof arr === 'number') {return {value: arr } } else if(Array.isArray(arr)) { return { children: Arr. The map (I = > {return the transition (I)})}}} the console. The log (transition ([1, 2, 3, 4, 5]]));Copy the code

It looks like it will work, and it’s been very successful in getting the code down to 15 lines. In view of my limited technical level, I have no clue about how to reduce the number of cycles to improve performance, so I hope you can give me some suggestions.

If you have a better way, welcome to comment below, let everyone progress together.

3. Write a setInterVal(fn, a, b) at intervals a, A +b,a+2b, and then write a stop to stop the setInterVal

The first time I did this, INSTEAD of using a constructor, I wrote a normal function that automatically executed when I called it by simply writing in the parameters.

function mySetInterVal(fn, a, b, End = 2) {let time = 0 ↓ let handle = null function stop () {end = 2) {let time = 0 ↓ let handle = null Console. log(' stopped refreshing, now ${a + b * time} '); clearTimeout(handle) time = 0 } function setTime(a, B) {if(time > end) return stop() handle = setTimeout(() => {time++ fn() console.log(' now ${a + b*time} '); SetTime (a, b)}, a + b * time)} return setTime(a, b)} let test2 = mySetInterVal(() => {console.log(' I am a function ')}, 1000, 500).Copy the code

It did meet the requirements, but it didn’t feel very good. So let’s replace it with a constructor. Switch to constructors

/ / -- -- -- -- -- into the constructor -- -- -- -- -- the function mySetInterVal (fn, a, b, end = 2) { this.num = 0 this.handle = null this.end = () => { this.num = 0 clearTimeout(this.handle) } this.start = () => {this.handle = setTimeout(() => {if(this.num > end) {console.log(' stop refresh, now refresh time ${a+b*this.num} '); Return this. The end () / / < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- if required to call me to stop, Are commented out good} this. Num++ this. Start (fn) () the console. The log (` now is ${a} + ${b * enclosing num} `); }, a + b * this.num)}} let test = new mySetInterVal(() => {console.log(' I am a function ')}, 1000, 500) test.start()Copy the code

It doesn’t seem to have changed much, but using constructors sounds a bit better than normal functions. Letting the interviewer know that you know how to use constructors should also be a small plus (or maybe not a plus, but it’s better to write it in a more advanced way than the simplest way). Or by creating a class implementation.

Create a class class

----- create a class class----- class mySetInterVal {constructor(fn, a, b,) end=2) { this.a = a this.b = b this.fn = fn this.time = 0 this.end = end this.handle = null } timeStart() { if(this.time > this.end) {return this.timeend ()} this.handle = setTimeout(() => {console.log(' now ${this.a}+${this.b*this.time} ');  this.time++ this.timeStart() }, this.a + this.b * this.time) } timeEnd() { clearTimeout(this.handle) this.time = 0 } } let test = new mySetInterVal(() => {console.log(' I am a function ')}, 1000, 500) test.timestart ()Copy the code

Creating a class to implement it should look a bit fresher than someone else doing it with a function. At the very least, let the interviewer know that you are a good user.

If you have other methods, please point out more, we progress together!

In terms of front-end video, you can pay attention to my B station and search for “Doudou is not boring”. There are videos uploaded from front-end entry to mastery (1000 big collection), zero-based play on wechat mini program, correct posture of using Webview in 5G era, etc. You can also enter the front-end development communication group and chat with everyone to learn oh:Click here to enter the learning circle