当前位置:网站首页>JS brain burning interview question reward

JS brain burning interview question reward

2022-04-23 13:52:00 JackieZhengChina

This article selects 20 Multichannel, somewhat confusing js topic , It mainly focuses on type judgment 、 Scope 、this Point to 、 Prototype 、 Knowledge points such as event cycle , Each question is equipped with a detailed fool's analysis , Prefer beginners , Please feel free, big man .

The first 1 topic

let a = 1
function b(a) {
  a = 2
  console.log(a)
}
b(a)
console.log(a)

answer

2、1

analysis

First, basic type data is passed by value , So execute b Function time ,b Parameters of a Received value is 1, Parameters a Equivalent to a variable inside a function , When this scope has a variable with the same name as the upper scope , Unable to access upper level variable , So no matter how you modify it in the function a, It doesn't affect the upper layer , So the internal printing of the function a yes 2, It's still printed on the outside 1.

The first 2 topic

function a (b = c, c = 1) {
  console.log(b, c)
}
a()

answer

Report errors

analysis

Setting default values for multiple parameters of a function is actually the same as defining variables in order , So there will be a temporary dead zone , That is, variables defined earlier cannot refer to variables not defined later , The latter can access the former .

The first 3 topic

let a = b = 10
;(function(){ 
  let a = b = 20 
})()
console.log(a)
console.log(b)

answer

10、20

analysis

Even operations are performed from right to left , amount to b = 10、let a = b, Obviously b Without declaration, it is directly assigned , So it will be implicitly created as a global variable , The same is true for functions , There is no claim b, That's right b Assigned a value to , Because the scope chain , Will look up layer by layer , Found Global b, So overall b It was changed to 20 了 , And inside the function a Because it was restated , So it's just a local variable , Not affecting global a, therefore a still 10.

The first 4 topic

var a = {n:1}
var b = a
a.x = a = {n:2}
console.log(a.x)
console.log(b.x)

answer

undefined、{n: 2}

analysis

I'm sorry I'm not talented , The author makes a mistake once in a while .

Anyway, according to most online explanations, it's because . Operator has the highest priority , So it's going to execute first a.x, here a、b Co directed {n: 1} Turned into {n: 1, x: undefined}, Then execute the code from right to left according to the continuous operation ,a = {n: 2}, obviously ,a Now point to a new object , then a.x = a, because a.x It was executed at the beginning , So this is actually equivalent to :({n: 1, x: undefined}).x = b.x = a = {n: 2}.

The first 5 topic

var arr = [0, 1, 2]
arr[10] = 10
console.log(arr.filter(function (x) {
  return x === undefined
}))

answer

[]

analysis

This question is relatively simple ,arr[10]=10, Then index 3 To 9 It's all in position undefined,arr[3] It's true when it's printed out undefined, however , This actually involves ECMAScript Different versions correspond to problems with different method behaviors ,ES6 Before traversing the array, all the unassigned methods will be skipped , That is, vacant seats , however ES6 Newly added for of Method will not be skipped .

The first 6 topic

var name = 'World'
;(function () {
  if (typeof name === 'undefined') {
    var name = "Jack"
    console.info('Goodbye ' + name)
  } else {
    console.info('Hello ' + name)
  }
})()

answer

Goodbye Jack

analysis

This question examines the problem of variable Promotion ,var When a variable is declared, it will be automatically promoted to the top of the current scope , So... In the function name Though it is if Declared in branch , But it will also ascend to the outer layer , Because and global variables name The nuptial , So you can't access the outer layer name, Finally, because the declared unassigned variables have values of undefined, Lead to if The first branch of satisfies the condition .

The first 7 topic

console.log(1 + NaN)
console.log("1" + 3)
console.log(1 + undefined)
console.log(1 + null)
console.log(1 + {})
console.log(1 + [])
console.log([] + {})

answer

NaN、13、NaN、1、1[object Object]、1、[object Object]

analysis

The problem is obviously + Behavior of No :

1. If an operand is a string , Then convert another operand to a string to execute the connection

2. If an operand is an object , So call the object's valueOf Method to original value , If there is no such method or it is still non original after calling , Call toString Method

3. In other cases , Both operands are converted to numbers to perform an addition operation

The first 8 topic

var a={},
    b={key:'b'},
    c={key:'c'}
a[b]=123
a[c]=456
console.log(a[b])

answer

456

analysis

Object has two ways to set and reference properties ,obj.name and obj['name'], Strings can be in square brackets 、 Numeric and variable settings are expressions, etc , But the final calculation is a string , For the top b and c, They are both objects , So I call toString() Method to string , Object to string is different from array , Nothing to do with the content , The result is [object Obejct], therefore a[b]=a[c]=a['[object Object]'].

The first 9 topic

var out = 25
var inner = {
  out: 20,
  func: function () {
    var out = 30
    return this.out
  }
};
console.log((inner.func, inner.func)())
console.log(inner.func())
console.log((inner.func)())
console.log((inner.func = inner.func)())

answer

25、20、20、25

analysis

This question is about this Point to the problem :

1. The comma operator returns the last value in the expression , Here for inner.func Corresponding function , Notice the function itself , Then execute the function , The function is not called through the method of the object , Instead, call... In a global environment , therefore this Point to window, Printed out, of course window Under the out

2. This is obviously called as a method of an object , that this Point to the object

3. Added a bracket , It looks a little confusing , But actually (inner.func) and inner.func It's exactly the same , So it's still a method call as an object

4. Assignment expressions are similar to comma expressions , Are the returned values themselves , So it's also relative to calling functions in a global environment

The first 10 topic

let {a,b,c} = { c:3, b:2, a:1 }
console.log(a, b, c)

answer

1、2、3

analysis

This problem examines the problem of variable deconstruction and assignment , Array deconstruction assignment is based on position , And the object as long as the variable has the same name as the attribute , Random order .

The first 11 topic

console.log(Object.assign([1, 2, 3], [4, 5]))

answer

[4, 5, 3]

analysis

Has it never worked assign Method merged arrays ?assign Method can be used to handle arrays , However, the array will be treated as an object , For example, the target array will be treated as an attribute of 0、1、2 The object of , So the source array 0、1 The value of the property overrides the value of the target object .

The first 12 topic

var x=1
switch(x++)
{
  case 0: ++x
  case 1: ++x
  case 2: ++x
}
console.log(x)

answer

4

analysis

This question examines the prefix version and suffix version of the self increasing operator , as well as switch The grammar of , The suffix version of the autoincrement operator does not occur until the statement is evaluated , therefore x Will still 1 Value to match case Branch , So it obviously matches 1 The branch of , here ,x++ take effect ,x become 2, Re execution ++x, become 3, Because no break sentence , So it will enter the current case The back branch , So again ++x, Eventually it becomes 4.

The first 13 topic

console.log(typeof undefined == typeof NULL)
console.log(typeof function () {} == typeof class {})

answer

true、true

analysis

1. First of all, don't put NULL As a null,js Keywords are case sensitive , So this is an ordinary variable , And no statement ,typeof There is no error when using undeclared variables , return 'undefined',typeof Yes undefined The use is also 'undefined', So the two are equal

2.typeof Use return for function 'function',class It's just es6 New syntax sugar , It's essentially a function , So the two are equal

The first 14 topic

var count = 0
console.log(typeof count === "number")
console.log(!!typeof count === "number")

answer

true、false

analysis

1. There's nothing to say ,typeof Return for numeric type 'number'.

2. This question is about the priority of the operator , Logic is not ! Priority over congruence === high , So first execute !!typeof count, The result is true, And then execute true === 'number', The result, of course, is false, You can click here to view the priority list :
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table.

The first 15 topic

"use strict"
a = 1
var a = 2
console.log(window.a)
console.log(a)

answer

2、2

analysis

var The declaration raises the variable to the top of the current scope , therefore a=1 No errors are reported , In addition, use... Under the global scope var Declare variables , The variable becomes window A property of , Both of the above points have nothing to do with whether you are in strict mode .

The first 16 topic

var i = 1
function b() {
  console.log(i)
}
function a() {
  var i = 2
  b()
}
a()

answer

1

analysis

This question is about the scope , A scope is actually a set of variable search rules , Each function creates an execution context when executing , Which will be associated with a variable object , That is, its scope , It holds all the variables that the function can access , In addition, the code in the context also creates a scope chain when executing ,

If an identifier is not found in the current scope , Will continue to search along the outer scope , Up to the top global scope , because js It's lexical scope , In the code writing phase, the scope has been determined , let me put it another way , It's defined when the function is defined , Not when it's executed , therefore a Functions are defined in the global scope , Although in b Call inside function , But it can only access the global scope, not b The scope of the function .

The first 17 topic

var obj = {
  name: 'abc',
  fn: () => {
    console.log(this.name)
  }
};
obj.name = 'bcd'
obj.fn()

answer

undefined

analysis

This question is about this Direction problem of , When the arrow function is executed, the context will not be bound this Of , So what's in it this Depends on the outer layer this, Here, when the function is executed, the outer layer is the global scope , therefore this Point to window,window There is no name attribute , So it is undefined.

The first 18 topic

const obj = {
  a: {
    a: 1
  }
};
const obj1 = {
  a: {
    b: 1
  }
};
console.log(Object.assign(obj, obj1))

answer

{a: {b: 1}}

analysis

The problem is very simple , because assign Method performs a shallow copy , So the source object's a Property directly overrides the of the target object a attribute .

The first 19 topic

console.log(a)
var a = 1
var getNum = function() {
  a = 2
}
function getNum() {
  a = 3
}
console.log(a)
getNum()
console.log(a)

answer

undefined、1、2

analysis

First of all, because var Declared variable promotion , therefore a The variable is promoted to the top , Unassigned , So the first print out is undefined.

Next is the difference between function declaration and function expression , Function declarations can have a lifting effect , Raise the function to the top before code execution , Generate function definitions on the execution context , So the second one getNum Will be lifted to the top first , And then there was var Statement getNum The promotion of , But because getNum The function has been declared , So there is no need to declare a variable with the same name ,

Next, start executing the code , Execute to var getNum = fun... when , Although the statement was advanced , But the assignment operation remains here , therefore getNum Is assigned to a function , The following function declaration directly skips , Last ,getNum Before function execution a Print it out or 1, After execution ,a It was modified to 2, So the last printed out 2.

The first 20 topic

var scope = 'global scope'
function a(){
  function b(){ 
    console.log(scope)
  }
  return b
  var scope = 'local scope'
}
a()()

answer

undefined

analysis

This question is still about variable promotion and scope , although var The statement is in return Statement behind , But it will still be promoted to a Top of function scope , Then because the scope is determined when the function is defined , It's not about the call location , therefore b The upper scope of is a function ,scope stay b Not found in its scope , Look up and find the automatically promoted and unassigned scope Variable , So print out undefined.

The first 21 topic

function fn (){ 
  console.log(this) 
}
var arr = [fn]
arr[0]()

answer

Print out arr The array itself

analysis

Function is called as a method of an object ,this Point to the object , Arrays are obviously also objects , It's just that we're all used to the method of object referencing properties :obj.fn, But actually obj['fn'] References are also possible .

The first 22 topic

var a = 1
function a(){}
console.log(a)

var b
function b(){}
console.log(b)

function b(){}
var b
console.log(b)

answer

1、b The function itself 、b The function itself

analysis

These three topics all involve function declaration and var Statement , Both will improve , But the function will be promoted first , So if a variable has the same name as a function , The promotion of variables is ignored .

1. After lifting , Execute to assignment code ,a Assigned to 1, Function because it has been declared to promote , So skip , Finally print a Namely 1.

2. Similar to the first question , It's just b No assignment operation , Then executing these two lines is equivalent to no operation ,b Function, of course .

3. Similar to question 2 , Just a change of order , But it does not affect the promotion order of the two , Still function first , Homonymous var Declaration promotion ignored , So print out b Or function .

The first 23 topic

function Foo() {
  getName = function () { console.log(1) }
  return this
}
Foo.getName = function () { console.log(2) }
Foo.prototype.getName = function () { console.log(3) }
var getName = function () { console.log(4) }
function getName() { console.log(5) }

// Please write the following output :
Foo.getName()
getName()
Foo().getName()
getName()
new Foo.getName()
new Foo().getName()
new new Foo().getName()

answer

2、4、1、1、2、3、3

analysis

This is a comprehensive topic , First getName The function declaration will be promoted first , then getName Function expression Promotion , But because function declarations promote online , So ignore the promotion of function expressions , Then start executing the code , Execute to var getName= ... when , Revised getName Value , The assignment is printed 4 The new function of .

1. perform Foo Static method of function , Print out 2.

2. perform getName, At present getName Yes, print out 4 The function of .

3. perform Foo function , Changed global variables getName, The assignment is printed 1 Function of , Then return this, Because it is executed in a global environment , therefore this Point to window, because getName It has been modified , So print out 1.

4. because getName It has not been reassigned , So execute again and still print out 1.

5.new Operators are used to call functions , therefore new Foo.getName() amount to new (Foo.getName)(), therefore new Yes. Foo Static method of getName, Print out 2.

6. Because the dot operator (.) Priority and new It's the same height , So execute from left to right , amount to (new Foo()).getName(), Yes Foo Use new The call will return a newly created object , Then execute the of the object getName Method , The object itself does not have the method , So it will come from Foo On the prototype object , eureka , So print out 3.

7. It's the same as the last question , Dot operator (.) Priority and new As high as , in addition new It's used to call functions , therefore new new Foo().getName() amount to new ((new Foo()).getName)(), In parentheses is the last question , So the last thing I found was Foo The archetypal approach , Whether it's a direct call , Or through new call , Will execute this method , So print out 3.

The first 24 topic

const person = {
 address: {
  country:"china",
  city:"hangzhou"
 },
 say: function () {
  console.log(`it's ${this.name}, from ${this.address.country}`)
 },
 setCountry:function (country) {
  this.address.country=country
 }
}

const p1 = Object.create(person)
const p2 = Object.create(person)

p1.name = "Matthew"
p1.setCountry("American")

p2.name = "Bob"
p2.setCountry("England")

p1.say()
p2.say()

answer

it's Matthew, from England

it's Bob, from England

analysis

Object.create Method creates an object , And the object's __proto__ Property points to the incoming object , therefore p1 and p2 The prototype object of two objects points to the same object , Then give p1 Added a name attribute , And then it calls p1 Of setCountry Method ,p1 There is no such method in itself , So it will look up along the prototype chain , On its prototype , That is to say person Found this method on the object , Executing this method will give address Object's country Property to set the value passed in ,p1 Not in itself address Attribute ,

But and name Properties are different ,address Property found on prototype object , And because it's a reference value , So it will be modified successfully country attribute , Then on p2 The same is true for , Then, because there are references in the prototype, the values will be shared in all instances , therefore p1 and p2 They refer to address It's the same object , An example has been modified , Will be reflected on all instances , therefore p2 Your changes will be overwritten p1 Modification of , Final country The value of is England.

The first 25 topic

setTimeout(function() {
  console.log(1)
}, 0)
new Promise(function(resolve) {
  console.log(2)
  for( var i=0 ; i<10000 ; i++ ) {
    i == 9999 && resolve()
  }
  console.log(3)
}).then(function() {
  console.log(4)
})
console.log(5)

answer

2、3、5、4、1

analysis

This question obviously examines the knowledge points of the event cycle .

js It is a single-threaded language , But in order to perform some asynchronous tasks without blocking code , And avoid waste of resources during waiting ,js There is a mechanism for event loops , Single thread refers to execution js The thread of , Called the main thread , There are other threads, such as network request threads 、 Timer thread , The main thread will generate an execution stack when running , If the code in the stack calls asynchronous api If so, the event will be added to the event queue ,

As long as the asynchronous task has a result, it will put the corresponding callback into 【 Task queue 】 in , When the code in the execution stack is executed, it will read the tasks in the task queue , Put it on the main thread for execution , When the execution stack is empty, it will check , So back and forth , That is, the so-called event cycle .

Asynchronous tasks are divided into 【 Macro task 】( such as setTimeout、setInterval) and 【 Micro task 】( such as promise), They will enter different queues , After the execution stack is empty, the micro task queue will be checked first , If there are micro tasks, all micro tasks will be executed at one time , Then go to the macro task queue to check , If so, take out a task to the main thread to execute , After execution, you will check the micro task queue , So circular .

Back to the question , First, the whole code starts executing as a macro task , encounter setTimeout, The corresponding callback will enter the macro task queue , And then there was promise,promise The callback is the synchronization code , So it prints out 2,for When the loop ends, it is called. resolve, therefore then The callback will be put into the micro task queue , Then print out 3, Last printed out 5, At this point, the current execution stack is empty , So first check the micro task queue , Found a task , Then take it out and put it into the main thread to execute , Print out 4, Finally, check the macro task queue , Put the callback of the timer into the main thread to execute , Print out 1.

The first 26 topic

console.log('1');

setTimeout(function() {
  console.log('2');
  process.nextTick(function() {
    console.log('3');
  });
  new Promise(function(resolve) {
    console.log('4');
    resolve();
  }).then(function() {
    console.log('5');
  });
}); 

process.nextTick(function() {
  console.log('6');
});

new Promise(function(resolve) {
  console.log('7');
  resolve();
}).then(function() {
  console.log('8');
});

setTimeout(function() {
  console.log('9');
  process.nextTick(function() {
    console.log('10');
  }) 
  new Promise(function(resolve) {
    console.log('11');
    resolve();
  }).then(function() {
    console.log('12')
  });
})

answer

1、7、6、8、2、4、9、11、3、10、5、12

analysis

This question is similar to the last one , But there was process.nextTick, So obviously node In the environment ,node There is also the concept of event loops , But it's a little different from the browser ,nodejs The macro tasks in are divided into several different stages ,

Two timers belong to timers Stage ,setImmediate Belong to check Stage ,socket Closing event of close callbacks Stage , All other macro tasks belong to poll Stage ,

besides , Just go to a certain stage mentioned above , Then all the tasks in this stage will be completed , This is different from browsers , The browser takes one macro task at a time to execute , After execution, I ran to check the micro task queue ,

however nodejs Yes, they are , It's good to complete the tasks of this stage at one time , that process.nextTick And at what stage do micro tasks execute , At the end of each phase mentioned above, it will be executed , however process.nextTick Will take precedence over micro tasks , A picture is worth a thousand words :

It's easy to analyze this problem after understanding it , Execute the overall code first , Print out 1,setTimeout Callback throw in timers queue ,nextTick Throw in nextTick Queues ,promise The callback is the synchronization code , Print out after execution 7,then The callback is thrown into the micro task queue , And then there's another setTimeout Callback throw in timers queue , At this point, the current node is over ,

Check nextTick And micro task queue ,nextTick Queue has tasks , Print out after execution 6, There are also micro task queues , Print out 8, Next, check the stages in sequence ,check queue 、close callbacks There are no tasks in the queue , here we are timers Stage , Two tasks were found , Do the first one first , Print out 2, then nextTick Throw in nextTick Queues , perform promise Print out 4,then The callback is thrown into the micro task queue ,

Carry out the second setTimeout The callback , Print out 9, Then just like before ,nextTick Throw in nextTick Queues , perform promise Print out 11,then The callback is thrown into the micro task queue , Come here timers The stage is over , perform nextTick Queue tasks , Two more tasks were found , Execute sequentially , Print out 3 and 10, Then check the micro task queue , It's also two tasks , Execute sequentially , Print out 5 and 12, Here, the queue is empty .

author : Kobayashi on the corner

https://juejin.cn/post/6989433079760683022

 

版权声明
本文为[JackieZhengChina]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231351328389.html