Well, white’s way of attacking, continue to complement… And saw some pits, their first negligence to do wrong, or with notes down, common progress

Well, the interview series and the pit will be updated on Github, and friends who are preparing for autumn recruitment can pass by under STAR, and progress together

JS special

1. The magic of arrays

What is the following output

var arr1 = "john".split(' ');
var arr2 = arr1.reverse();
var arr3 = "jones".split(' ');
arr2.push(arr3);
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(- 1));
console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(- 1));
Copy the code

The answer:

"array 1: length=5 last=j,o,n,e,s"
"array 2: length=5 last=j,o,n,e,s"
Copy the code

Yes, I find the two outputs are the same, so let’s get to the core of the problem and think about it

  • Arrays are not simple data types (value types) and are stored in the heap when usedvar arr1 = arr2When you assign it, it’s just a shallow copy, and you get itarr2The problem with this is that it is modifiedarr1whenarr2Will also be affected.
  • arr1.push(arr2)That’s why there’s a function calledconcat.pushI’m just going to push the whole array in, not separate these two points, and we’re basically done.

2. Confusion of the + – operator

What is the following program output?

console.log(1 +  "2" + "2");
console.log(1 +  +"2" + "2");
console.log(1 +  -"1" + "2");
console.log(+"1" +  "1" + "2");
console.log( "A" - "B" + "2");
console.log( "A" - "B" + 2);
Copy the code

The answer:

"122"
"32"
"."
"112"
"NaN2"
NaN
Copy the code

Well, the core is the following points, and think about it carefully yourself

  • - +Will implicitly convert toNumbertype
  • when+Appears as an operatorStringBefore the type, string concatenation is assumed to be required, so it is implicitly cast toString
  • NumberContains a special type NaN, which is changed when Number is converted to a non-number.

Note that the + sign in front of the second 2 is consistent with the first, so the second 2 is converted to the Number type. Answer: 32 Using PI (1), PI (3), obviously NaN2, same thing in problem 6

3. Stack overflow puzzle

The following code will cause stack overflow, how to optimize, not change the original logic

var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...nextListItem(); }};Copy the code

The answer:

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        setTimeout(nextListItem,0}};Copy the code

The first thing we have to figure out is why the stack overflows.

In JS, careless operations or programming habits can easily cause stack overflows, especially when doing callbacks or loops. The following is a quote to explain the overflow:

Because each time you execute the code, will be allocated a certain size of the stack space (Windows system for 1 m), each method call in the stack store certain information (such as parameters, local variables, return value, etc.), the information be less will also occupy a certain space, accumulated tens of thousands of these Spaces, naturally over the thread stack space. So how to solve such problems?

Here are two ideas to solve this problem:

  1. asynchronous
  2. closure

Obviously, this is the first method to use, closures. Why does setTimeout solve the problem? Let’s see the difference between the two. If setTimeout is not used, then the function will continue to call back before the big data until it finally gets to the point where the original function finishes running and frees up memory. But if setTimeout is used, we know that it is asynchronous, and even if the time is set to 0, it allows the following to be executed first, freeing the stack and avoiding stack overflows. In other words, with setTimeout, the nextListItem function is pushed into the event queue and the function can exit, thus emptying the call stack each time.

The same is true with closures, because the first is the most appropriate answer to the problem of not modifying the logic, and of course the way to avoid using closures is to return a function

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        return nextListItem()
    }
};
Copy the code

Of course, doing this changes the way the function is called, and we need to keep calling nextListItem()()() to handle this method, we can further encapsulate it

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        return function() {
            return nextListItem()
        }
    }
};

function autoRun(fun) {
    var value = nextListItem();
    while(typeof value === 'function') {
        value = nextListItem()
    }
    return
}
Copy the code

This solves the stack overflow problem. Here’s where closure ideas come from and stack overflow solutions

4. Do you really know the key of an Object?

What is the output of the following function?

var a={},
    b={key:'b'},
    c={key:'c'};

a[b]=123;
a[c]=456;

console.log(a[b]);
Copy the code

Answer: The output looks like 456, not 123, at least I’m a little out…

The reason? If you are familiar with ES6’s new map data type, you should realize that, yes, the key value of an object is allowed to be String only, which is why the map data type was introduced. Okay, so if you take an object as a key, you call toString.

Object. The prototype. ToString (obj) what you’re gonna get? Object object. That so

a[b] ==> a["[object Object"] = 123;
a[b] ==> a["[object Object"] = 456;
Copy the code

The answer is obvious

Palindrome judgment

Please do a palindrome judgment function, determine whether palindrome

Answer: This is a very simple, very general method. Linked list is the best way to judge palindromes, of course, thanks to the flexible method of JS array, can be easier to implement.

Here we mainly consider a robustness problem, with a regular to check:

function check(str) {
    str = str.replace(/\W/g.' ').toLowerCase();
    return str === str.split(' ').reverse().join()
}
Copy the code