Cheng Xing naked resignation heart very cool, interview work repeatedly suffer. Lucky to have a daily companion, click attention mo lazy.

It is the job-hopping season of Jin Jiu Yin Shi again. In order to let more partners get better offers in the interview, I have been pushing one or two interview questions on my official account since last month, commonly known as Daily One question (daily One pit). Convenient to find a job partners will have a new harvest every day. This article is a small series of early some of the more classic daily questions combed, welcome to have a look. This article was first published in the public number [front-end some play], pay attention to === learn.

A class array related interview question

What is a class array? A class array is an object that has the length attribute, the other attributes (indexes) are non-negative integers, and does not have the methods used by the array. Such as we often use the document. QuerySelectorAll return NodeLists is a class array. This is all about class arrays.

The title

Name the output of the following code. You need to distinguish between Nodejs, Chrome, and chrome output without splice

var obj = {
    '2': 3.'3': 4.'length': 2.'splice': Array.prototype.splice,
    'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
Copy the code

The answer

There are three cases that this question asks and the following output shows the answers in turn

  1. Output from node

    { '2': 1,
      '3': 2,
      length: 4,
      splice: [Function: splice],
      push: [Function: push] }
    Copy the code
  2. Chrome will output

    [empty × 2, 1, 2, splice: ƒ, push: ƒ]
    Copy the code
  3. Chrome remove the output below splice

    {2:1, 3:2, length: 4, push: ƒ}Copy the code

From the output above, it can be seen that the same code, the output content is different in different cases, the following is a detailed breakdown.

Answer key

Let’s look at this code again before we solve this problem

const arr = new Array(2)
// print 2 [empty * 2]
console.log(arr.length, arr)
arr.push(1)
// print 3 [empty * 2, 1]
console.log(arr.length, arr)
Copy the code

As you can see, the push method takes the array’s length + 1 and places the value at index length-1, as in the above code, because when initializing the array, The array length has been specified as 2, so after push the length becomes 3, and then arr[3-1] = 1

The MDN approach to push is explained as follows:

Push method has universality. This method, when used with call() or apply(), can be applied to array-like objects. The push method uses the length attribute to decide where to start inserting a given value. If length cannot be converted to a numeric value, the index of the inserted element is 0, including if length does not exist. Length will be created when it does not exist.

According to MDN, push can be used in both arrays and class arrays. Obj is a standard array of classes, so we can use the push method of array on obj.

Obj. Push (1), obj. Length = 2, obj[3-1] = 1, obj[2] = 1, obj. Push (2) is the same. Because obj already has attributes (indexes)2 and 3, push overrides the default values above 2 and 3.

So it’s going to be output in NodeJS

{ '2': 1,
  '3': 2,
  length: 4,
  splice: [Function: splice],
  push: [Function: push] }
Copy the code

But output it in the Chrome console

[empty × 2, 1, 2, splice: ƒ, push: ƒ]
Copy the code

Strange, why is this output? One particular pitfall here is how does the Chrome console determine whether the printed content is an array or some other object? Chrome does this by determining whether an object has splice and length on it, so if you remove splice, you’ll get the following output

{2:1, 3:2, length: 4, push: ƒ}Copy the code

You can also try the following code:

console.log({splice:function(){},length:1})
console.log({slice:function(){},length:1})
Copy the code

Logical interview question mice drink poison

Xiaobian graduation when the interview encountered several logic type of interview questions, this question is a logic type of interview questions, let’s have a look.

The title

There are 16 bottles of water, only one bottle of water is poisonous, the mice will die one hour after drinking a drop, how many mice can be used at least, in one hour we can find the toxic water?

Answer and solution

The answer is you need at least 4 mice. We can use binary reasoning:

Suppose there are 4 mice, respectively a, b, D, d, d, d, d, d, d, d, d, d, d, d, d, d, D

A: 1111 1111 0000 0000

B: 1111 0000 1111 0000

C: 1100 1100 1100

D: 1010 1010 1010 1010

Then we can judge:

  1. A YiBingDing are dead, the first bottle poisonous
  2. A, B and C are dead, which means the second bottle was poisoned
  3. Acetin’s dead, which means the third bottle was poisoned
  4. A and B are dead, which means the fourth was poisoned
  5. Gabingtin’s dead, which means the fifth was poisoned
  6. . So on

You can actually use 2 to the NTH power for this problem, if you have 32 bottles of water, that’s 2 to the fifth power, so you need 5 mice.

The arguments of interview questions

In ES6, if a function has an indefinite number of arguments, we usually use the extension operator function(… Rest){}, get an array of arguments rest, but prior to ES6 we couldn’t use extended operators, so consider using arguments

The title

Say the following program output (Chrome output)

let obj = {
  age: 18.foo: function(func) {
    func()
    arguments[0] ()}}var age = 10
function fn() {
  console.log(this.age)
}

obj.foo(fn)
Copy the code

The answer

The answer to this question is:

// First output 10
func()
// The first output is undefined
arguments[0] ()Copy the code

A little out of the blue?

Func () is called inside foo, but the scope is not explicitly specified. The default scope is window. For browsers, variables declared globally via var are automatically mounted to window. So var age = 10 equals window.age = 10, and this.age in the first func() equals window.age

The second one may be a little confusing to many people, why undefined, first look at the following code

const arr = [function() {console.log(this[1])}, 'I am Zijun']
// I am zijun
console.log(arr[0] ())Copy the code

We get the function through arr[0], and the scope of the function is this array, so when we call this again, this is arr, so this[1] is the second item in the array.

Arguments [0] = function (age); arguments[0] = function (age); So it is undefined

This points to the problem

Before the advent of arrow functions, the orientation of this depended not on where code was defined, but on who was executing it, and because of this, many developers were often confused about who this was. The following two questions are related to the direction of this.

Title 1 (Bronze)

Say what the following code outputs

var num = 1;
let obj = {
    num: 2.add: function() {
        this.num = 3;
        (function() {
            console.log(this.num);
            this.num = 4; }) ();console.log(this.num);
    },
    sub: function() {
        console.log(this.num)
    }
}
obj.add();
console.log(obj.num);
console.log(num);
const sub = obj.sub;
sub();
Copy the code

Title two (Gold)

Say what the following code outputs

var num = 10
const obj = {num: 20}
obj.fn = (function (num) {
  this.num = num * 3
  num++
  return function (n) {
    this.num += n
    num++
    console.log(num)
  }
})(obj.num)
var fn = obj.fn
fn(5)
obj.fn(10)
console.log(num, obj.num)
Copy the code

The answer

Subject to a

Output: 1,3,3,4,4. Are you right? Let’s look at code parsing

var num = 1;
let obj = {
    num: 2.add: function() {
        this.num = 3;
      	// This points to the function immediately, because we didn't specify its this point manually, so it points to the window
        (function() {
            // this. Num is equal to window.num
            console.log(this.num);
            this.num = 4; }) ();console.log(this.num);
    },
    sub: function() {
        console.log(this.num)
    }
}
// The print is described line by line

/** * when the add function is called via obj. Add, Num =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3, obj =3 Num = 4 *, this. Num = obj, 3 */
obj.add() // Output 1, 3

// Obj. name has been changed to 3 by executing 'obj.add' above
console.log(obj.num) 3 / / output
// this num is window.num
console.log(num) / / output 4
// If obj.sub is assigned to a new variable, the scope of the function becomes the scope of the new variable
const sub = obj.sub
// The scope becomes window window.num is 4
sub() / / output 4
Copy the code
Topic 2

The output is: 22, 23, 65, 30. Are you right? So let’s parse it

var num = 10
const obj = {num: 20}
obj.fn = (function (num) {
  this.num = num * 3
  num++
  return function (n) {
    this.num += n
    num++
    console.log(num)
  }
})(obj.num)
var fn = obj.fn
fn(5)
obj.fn(10)
console.log(num, obj.num)
Copy the code

Let’s break down the above code into the following steps

  1. So let’s look at the third line of code, it’s an assignment, and we know that the assignment goes from right to left, and to the right of the = sign is an immediate function, so it takes precedence over the immediate function, immediate function without specifying this manually, so this = window, The num argument to the immediate function is the obj.num argument passed in, so the num argument defaults to 20

  2. The fourth line equals window.num = 20 * 3

  3. The fifth line adds one to the argument passed in, so num = 20 + 1

  4. The sixth line returns a function that is the value of obj.fn, but because the return function references num in the immediate function, it forms a closure. At this time

    obj.fn = function(n) {
      this.num += n
      // this num is the num in the immediately executed function
      num++
      console.log(num)
    }
    Copy the code
  5. Var fn = obj.fn, assigns obj.fn to a new variable whose scope is window

  6. Num += n = window.num += n = window.num = 65

  7. Num ++, because of the closure, the third step num is 21, so this step num becomes 22, and the output is 22

  8. This. Num += n = obj.num += 10

  9. As in step 7, num + 1 prints 23

  10. Console. log(num, obj.num) is console.log(window.num, obj.num), window.num = 65, obj.num = 30.

Extend the topic

If you change var to let, what will be the output?

Data type conversion problems

Although in daily development, we use less implicit type conversion (not necessarily), but this is often asked questions, master or master, let’s take a look at this topic.

Title (King fried/bronze, I don’t know)

Say what the following code outputs

console.log([] + [])
console.log({} + [])
console.log([] == ! [])console.log(true + false)
Copy the code

The answer

Take a look at the answers

  1. First line of code
// Prints "" empty string
console.log([] + [])
Copy the code

This line of code outputs an empty string “”, and when the wrapper type is evaluated, valueOf is called first. If valueOf returns the wrapper type again, toString is called

// Array again
const val = [].valueOf()
// array toString defaults to separate array entries with commas ",", such as [1,2,3]. ToString becomes "1,2,3", and empty array toString is empty string
const val1 = val.toString() // val1 is an empty string
Copy the code

So the code above is equivalent to

console.log("" + "")
Copy the code
  1. Second line of code

    // "[object object]"
    console.log({} + [])
    Copy the code

    As in the first question, {} is converted to [object object] and then added to “”

  2. Line 3

    / / output true
    console.log([] == ! [])Copy the code

    For ===, the values are strictly compared, but not for ==

    1. Such asnull == undefined
    2. If thenumberwithnumberThe comparison will convert it tonumber
    3. If one of the parties being compared isboolean, then will firstbooleanconvertnumber

    So for the above code, take a look at the following step by step analysis

    // This output is false
    console.log(! [])// Apply the third rule above to convert false to a value
    // This output is 0
    console.log(Number(false))
    // Wrapper type and base type == The wrapper type is converted to the base type by valueOf toString
    / / output ""
    console.log([].toString())
    // Convert an empty string to a numeric value.
    / / 0
    console.log(Number(""))
    / / so
    console.log(0= =0)
    Copy the code
  3. Line 4

    / / output 1
    console.log(true + false)
    Copy the code

    Two basic types are added, if one of them is a character, the others are converted to a character addition, otherwise the type is converted to Number, then added, Number(true) is 1, Number(false) is 0, so the result is 1

conclusion

Interview builds a rocket, work turns a screw. Although I just want to screw, but I need to find a job by building a rocket screw, a daily question, every day there are new interview questions, welcome to pay attention to the public number [front-end some play], pull you into the front-end technology exchange group, a daily question is waiting for you to answer together.

conclusion

Don’t blow out your inspiration and your imagination; Don’t be a slave to your model. — Vincent Van Gogh