Preface:

The output of the code is often tested in the interview, a piece of code may involve a lot of knowledge points, which examines the basic ability of the applicant. In the front end interview, often tested code output questions mainly involve the following knowledge points: asynchronous programming, event loop, this pointing, scope, variable promotion, closure, prototype, inheritance, etc., these knowledge points often do not appear alone, but in the same piece of code contains several knowledge points. Therefore, the author will be roughly divided into four categories for discussion. Here will not systematically elaborate the basic knowledge, but through the form of interview sample questions, to describe the knowledge points of each topic and code implementation process. If you know these examples, most code output problems can be solved easily in front of the interview.

Note: all examples in this article are collected from the Niuke network surface, network blog, if infringement, please contact delete!

The following is a series of articles.

[1] “2021” high frequency front face test summary HTML article

[2] “2021” high-frequency front end of the CSS section

[3] 2021

[4] 2021

[5] “2021”

[6] “2021”

【7】 “2021” High-Frequency front end test questions summary

[8] “2021” high frequency front end test questions summary

[9] “2021” high frequency front end test question summary of computer network article

[10] “2021” high frequency front end test summary of browser principles

[11] the performance optimization of “2021” high frequency test paper summary

[12] “2021” high frequency front end of the handwritten code of the test summary

[13] “2021” high frequency front end test summary code output results

1. Asynchrony & Event loops

1. Code output

const promise = new Promise((resolve, reject) = > {
  console.log(1);
  console.log(2);
});
promise.then(() = > {
  console.log(3);
});
console.log(4);
Copy the code

The output is as follows:

1 
2 
4
Copy the code

Promise. Then is a microtask that will not be executed until all the macro tasks have been executed. It also requires the promise’s internal state to change.

2. Code output

const promise1 = new Promise((resolve, reject) = > {
  console.log('promise1')
  resolve('resolve1')})const promise2 = promise1.then(res= > {
  console.log(res)
})
console.log('1', promise1);
console.log('2', promise2);
Copy the code

The output is as follows:

promise1
1 Promise{<resolved>: resolve1}
2 Promise{<pending>}
resolve1
Copy the code

Note that if you print PromisE1 directly, it will print out its status values and parameters.

The code execution process is as follows:

  1. Script is a macro task that executes the code in order;
  2. First, enter the Promise, execute the code in the constructor, and printpromise1;
  3. encounterresolveFunction,promise1The state of is changed toresolvedAnd save the results;
  4. encounterpromise1.thenThis microtask, put it on the microtask queue;
  5. promise2Is a new statependingthePromise;
  6. Execute sync code 1 and print outpromise1The state isresolved;
  7. Execute sync code 2 and print outpromise2The state ispending;
  8. Macro task execution is completed, search for microtask queue, foundpromise1.thenThis microtask has a state ofresolved, execute it.

3. Code output

const promise = new Promise((resolve, reject) = > {
  console.log(1);
  setTimeout(() = > {
    console.log("timerStart");
    resolve("success");
    console.log("timerEnd");
  }, 0);
  console.log(2);
});
promise.then((res) = > {
  console.log(res);
});
console.log(4);
Copy the code

The output is as follows:

1
2
4
timerStart
timerEnd
success
Copy the code

The code execution process is as follows:

  • When we encounter the Promise constructor, we first execute the contents and print1;
  • Encounter timersteTimeout, it is a macro task, put in the macro task queue;
  • Go ahead and print out 2;
  • Due to thePromiseThe state of theta is stillpending, sopromise.thenDo not execute first;
  • Continue with the synchronization task below and print 4;
  • In this case, there is no task in the microtask queue, and the next round of macro tasks is executedsteTimeout;
  • Executed firsttimerStart“And metresolveThat will bepromiseChange the status ofresolvedAnd save the result and change the previouspromise.thenPush to the microtask queue, and then executetimerEnd;
  • After executing the macro task, go to the microtaskpromise.thenTo print outresolveResults.

4. Code output

Promise.resolve().then(() = > {
  console.log('promise1');
  const timer2 = setTimeout(() = > {
    console.log('timer2')},0)});const timer1 = setTimeout(() = > {
  console.log('timer1')
  Promise.resolve().then(() = > {
    console.log('promise2')})},0)
console.log('start');
Copy the code

The output is as follows:

start
promise1
timer1
promise2
timer2
Copy the code

The code execution process is as follows:

  1. First of all,Promise.resolve().thenIs a microtask, join the microtask queue
  2. Execute timer1, which is a macro task, and join the macro task queue
  3. Continue with the synchronization code below and print outstart
  4. This completes the first round of macro tasks and starts executing microtasksPromise.resolve().thenTo print outpromise1
  5. encountertimer2, it is a macro task, add it to the macro task queue, then the macro task queue has two tasks, respectivelytimer1,timer2;
  6. This completes the first round of microtasks and starts the second round of macro tasks, starting with the timertimer1To printtimer1;
  7. encounterPromise.resolve().then, it is a microtask, join the microtask queue
  8. Start to execute tasks in the microtask queue, printpromise2;
  9. Finally, execute the macro tasktimer2Timer, print it outtimer2;

5. Code output

const promise = new Promise((resolve, reject) = > {
    resolve('success1');
    reject('error');
    resolve('success2');
});
promise.then((res) = > {
    console.log('then:', res);
}).catch((err) = > {
    console.log('catch:', err);
})
Copy the code

The output is as follows:

Then: success1Copy the code

After a Promise has changed, it will not change again. If the start state changes from pending to resolve, it indicates that the pending state has changed to resolve. If the pending state has changed from pending to resolve, it indicates that the pending state has changed to resolve. If the pending state has changed from pending to resolve, it indicates that the pending state has changed to resolve.

6. Code output

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)
Copy the code

The output is as follows:

1
Promise {<fulfilled>: undefined}
Copy the code

The promise. resolve method returns a new Promise object in the resolved state if the argument to the promise. resolve method is a raw value, or if it is an object that does not have the then method. Is also passed to the callback function.

The THEN method takes a function as an argument, and if it’s not passed a function, it actually interprets it as THEN (null), which causes the result of the previous Promise to be passed as follows.

7. Code output

const promise1 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve('success')},1000)})const promise2 = promise1.then(() = > {
  throw new Error('error!!! ')})console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() = > {
  console.log('promise1', promise1)
  console.log('promise2', promise2)
}, 2000)
Copy the code

The output is as follows:

promise1 Promise {<pending>}
promise2 Promise {<pending>}

Uncaught (in promise) Error: error!!!
promise1 Promise {<fulfilled>: "success"}
promise2 Promise {<rejected>: Error: error!! }Copy the code

8. Code output

Promise.resolve(1)
  .then(res= > {
    console.log(res);
    return 2;
  })
  .catch(err= > {
    return 3;
  })
  .then(res= > {
    console.log(res);
  });
Copy the code

The output is as follows:

1   
2
Copy the code

A Promise can be chained, because each call to a.then or.catch returns a new Promise, so it does not return this like a normal chained call to a task.

The output results are, in turn, print out the above 1 and 2, because the resolve (1) the method of first then after, not into the catch, so the second then the res get is actually the first then return values. And return 2 is wrapped as resolve(2), which is printed as 2 by the final THEN.

9. Code output

Promise.resolve().then(() = > {
  return new Error('error!!! ')
}).then(res= > {
  console.log("then: ", res)
}).catch(err= > {
  console.log("catch: ", err)
})
Copy the code

The output is as follows:

"then: " "Error: error!!!"
Copy the code

Return any value that is not a Promise will be wrapped as a Promise object, so return new Error(‘ Error!! Resolve (new Error(‘ Error!! ‘)), so it is caught by then instead of catch.

10. Code output

const promise = Promise.resolve().then(() = > {
  return promise;
})
promise.catch(console.err)
Copy the code

The output is as follows:

Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>
Copy the code

The value returned by the. Then or. Catch cannot be the promise itself, otherwise an infinite loop will be created.

11. Code output

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)
Copy the code

The output is as follows:

1
Copy the code

There’s really only one rule to keep in mind: arguments to.then or.catch are expected to be functions, and pass-through occurs if passed to a non-function.

The value of resolve(1) is passed directly to the last THEN, printing 1 directly. The value of resolve(1) is passed directly to the last THEN.

12. Code output

Promise.reject('err!!! ')
  .then((res) = > {
    console.log('success', res)
  }, (err) = > {
    console.log('error', err)
  }).catch(err= > {
    console.log('catch', err)
  })
Copy the code

The output is as follows:

error err!!!
Copy the code

We know that the.then function takes two arguments:

  • The first argument is the function that handles the Promise’s success
  • The second is the function that handles failures

That is, the value of promise.resolve (‘1’) goes into the successful function, and the value of promise.resolve (‘2’) goes into the failed function.

In this case, the error is caught directly by the second argument of the then, so it is not caught by the catch. The output is: error err!! ‘

However, if it is something like this:

Promise.resolve()
  .then(function success (res) {
    throw new Error('error!!! ')},function fail1 (err) {
    console.log('fail1', err)
  }).catch(function fail2 (err) {
    console.log('fail2', err)
  })
Copy the code

If an error is thrown in the first argument of the then, it will not be killed by the second argument, but will be caught by a later catch.

13. Code output

Promise.resolve('1')
  .then(res= > {
    console.log(res)
  })
  .finally(() = > {
    console.log('finally')})Promise.resolve('2')
  .finally(() = > {
    console.log('finally2')
  	return 'I'm the value returned by finally2.'
  })
  .then(res= > {
    console.log('Then function after finally2', res)
  })
Copy the code

The output is as follows:

1
finally2
finallyThe then function after finally22
Copy the code

.finally() is rarely used, just remember the following:

  • .finally()Method executes regardless of the final state of the Promise object
  • .finally()Method callbacks do not take any arguments, which means you are in.finally()There is no way to know what the final state of the Promise isresolvedorrejectedthe
  • It will eventually return the default value of the last Promise object, but if an exception is thrown it will return the exception’s Promise object.
  • Finally is essentially a special case of the then method

Error catching for.finally() :

Promise.resolve('1')
  .finally(() = > {
    console.log('finally1')
    throw new Error('I'm an exception thrown ina finally')
  })
  .then(res= > {
    console.log('Then function after finally', res)
  })
  .catch(err= > {
    console.log('Catch error', err)
  })
Copy the code

The output is:

'finally1'
'Catch error' Error: I am afinallyThe exception thrown inCopy the code

14. Code output result

function runAsync (x) {
    const p = new Promise(r= > setTimeout(() = > r(x, console.log(x)), 1000))
    return p
}

Promise.all([runAsync(1), runAsync(2), runAsync(3)]).then(res= > console.log(res))
Copy the code

The output is as follows:

1
2
3
[1.2.3]
Copy the code

First, a Promise is defined to asynchronously execute the function runAsync, which passes in a value of x and prints out the x after an interval of one second.

We then execute the function using promise. all, and see that after a second we print 1, 2, 3, and the array [1, 2, 3]. The three functions are executed synchronously, and all results are returned in a callback. And the results are executed in the same order as the function.

15. Code output result

function runAsync (x) {
  const p = new Promise(r= > setTimeout(() = > r(x, console.log(x)), 1000))
  return p
}
function runReject (x) {
  const p = new Promise((res, rej) = > setTimeout(() = > rej(`Error: ${x}`.console.log(x)), 1000 * x))
  return p
}
Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])
       .then(res= > console.log(res))
       .catch(err= > console.log(err))
Copy the code

The output is as follows:

// Output after 1s
1
3
// Output after 2s
2
Error: 2
// Output after 4s
4
Copy the code

You can see that. The catch catches the first error, which in this case is the result of runReject(2). If there is an exception in a set of asynchronous operations, it will not enter the first callback argument to.then(). Is caught by the second callback to.then().

16. Code output result

function runAsync (x) {
  const p = new Promise(r= > setTimeout(() = > r(x, console.log(x)), 1000))
  return p
}
Promise.race([runAsync(1), runAsync(2), runAsync(3)])
  .then(res= > console.log('result: ', res))
  .catch(err= > console.log(err))
Copy the code

The output is as follows:

1
'result: ' 1
2
3
Copy the code

Only the first successful method is captured by the THEN. All other functions continue to be executed, but are not captured by the THEN.

17. Code output result

function runAsync(x) {
  const p = new Promise(r= >
    setTimeout(() = > r(x, console.log(x)), 1000));return p;
}
function runReject(x) {
  const p = new Promise((res, rej) = >
    setTimeout(() = > rej(`Error: ${x}`.console.log(x)), 1000 * x)
  );
  return p;
}
Promise.race([runReject(0), runAsync(1), runAsync(2), runAsync(3)])
  .then(res= > console.log("result: ", res))
  .catch(err= > console.log(err));
Copy the code

The output is as follows:

0
Error: 0
1
2
3
Copy the code

You can see that after the catch catches the first error, the following code is not executed, but it will not be caught again.

Note: If all and race pass in an array with asynchronous tasks that throw exceptions, only the first thrown error will be caught, either by the second argument to then or by a subsequent catch. This does not affect the execution of other asynchronous tasks in the array.

18. Code output result

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}
async function async2() {
  console.log("async2");
}
async1();
console.log('start')
Copy the code

The output is as follows:

async1 start
async2
start
async1 end
Copy the code

The code execution process is as follows:

  1. The synchronization code in the function is first executedasync1 start“And then metawait, it will blockasync1The following code is executed, so it will be executed firstasync2Synchronization code inasync2“And jump outasync1;
  2. Jump out of theasync1Function to execute the synchronization codestart;
  3. Execute the macro after a round of macro tasks has been completedawaitWhat followsasync1 end.

We can understand that statements following the await are placed in the new Promise, and the next line and subsequent statements are placed in promise.then.

19. Code output result

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
  setTimeout(() = > {
    console.log('timer1')},0)}async function async2() {
  setTimeout(() = > {
    console.log('timer2')},0)
  console.log("async2");
}
async1();
setTimeout(() = > {
  console.log('timer3')},0)
console.log("start")
Copy the code

The output is as follows:

async1 start
async2
start
async1 end
timer2
timer3
timer1
Copy the code

The code execution process is as follows:

  1. First of all to enterasync1To print outasync1 start;
  2. After the encounterasync2And into theasync2, encounter timertimer2, join the macro task queue, and then printasync2;
  3. Due to theasync2Blocking the execution of the following code, so the following timer is executedtimer3, add it to the macro task queue, and then print itstart;
  4. Then execute the code after async2 and print outasync1 end, encounter timer timer1, add it to the macro task queue;
  5. Finally, the macro task queue has three tasks in ordertimer2.timer3.timer1, there are no microtasks, so all macro tasks are executed on a first-in, first-out basis.

20. Code output result

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve= > {
    console.log('promise1')})console.log('async1 success');
  return 'async1 end'
}
console.log('srcipt start')
async1().then(res= > console.log(res))
console.log('srcipt end')
Copy the code

The output is as follows:

script start
async1 start
promise1
script end
Copy the code

The important thing to note here is that in async1 the Promise after await has no return value, i.e. its state is always pending, so anything after await is not executed, including.then after async1.

21. Code output

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve= > {
    console.log('promise1')
    resolve('promise1 resolve')
  }).then(res= > console.log(res))
  console.log('async1 success');
  return 'async1 end'
}
console.log('srcipt start')
async1().then(res= > console.log(res))
console.log('srcipt end')
Copy the code

Resolve: Resolve: Resolve: Resolve: Resolve

The output is as follows:

script start
async1 start
promise1
script end
promise1 resolve
async1 success
async1 end
Copy the code

22. Code output

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}

async function async2() {
  console.log("async2");
}

console.log("script start");

setTimeout(function() {
  console.log("setTimeout");
}, 0);

async1();

new Promise(resolve= > {
  console.log("promise1");
  resolve();
}).then(function() {
  console.log("promise2");
});
console.log('script end')
Copy the code

The output is as follows:

script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
Copy the code

The code execution process is as follows:

  1. Async1 and async2 functions are defined at the beginning, but they do not execute the code in script, so print script start;
  2. Encounter timer Settimeout, which is a macro task, and add it to the macro task queue;
  3. Then we execute the function async1, which first prints out async1 start;
  4. When encountering await, execute async2, print asynC2 and block execution of subsequent code, adding subsequent code to the microtask queue;
  5. Async1, async2, promise1;
  6. If resolve is encountered, add it to the microtask queue, and then execute the following script code to print the script end.
  7. First print out async1 end, then print out promise2;
  8. After executing the microtask queue, the timer in the macro task queue is executed, printing out setTimeout.

23. Code output result

async function async1 () {
  await async2();
  console.log('async1');
  return 'async1 success'
}
async function async2 () {
  return new Promise((resolve, reject) = > {
    console.log('async2')
    reject('error')
  })
}
async1().then(res= > console.log(res))
Copy the code

The output is as follows:

async2
Uncaught (in promise) error
Copy the code

As you can see, if an error is thrown in the async function, it terminates the error result and does not continue down.

If you want the code following the error to execute, you can catch it using a catch:

async function async1 () {
  await Promise.reject('error!!! ').catch(e= > console.log(e))
  console.log('async1');
  return Promise.resolve('async1 success')
}
async1().then(res= > console.log(res))
console.log('script start')
Copy the code

The output is:

script start
error!!!
async1
async1 success
Copy the code

24. Code output result

const first = () = > (new Promise((resolve, reject) = > {
    console.log(3);
    let p = new Promise((resolve, reject) = > {
        console.log(7);
        setTimeout(() = > {
            console.log(5);
            resolve(6);
            console.log(p)
        }, 0)
        resolve(1);
    });
    resolve(2);
    p.then((arg) = > {
        console.log(arg);
    });
}));
first().then((arg) = > {
    console.log(arg);
});
console.log(4);
Copy the code

The output is as follows:

3
7
4
1
2
5
Promise{<resolved>: 1}
Copy the code

The code execution process is as follows:

  1. First you go to the Promise and print out a 3, then you go to the Promise below and print out a 7.
  2. Timer is encountered and added to the macro task queue.
  3. Run the resolve command in Promise P. The state becomes resolved and the return value is 1.
  4. Run the resolve command in Promise first. The state changes to Resolved and the return value is 2.
  5. When it encounters p.t. hen, add it to the microtask queue; when it encounters first().then, add it to the task queue;
  6. Execute the outside code and print 4;
  7. The first round of macro tasks is completed, and the tasks in the microtask queue are executed, printing 1 and 2 successively.
  8. The micro task is finished and the next macro task is executed. There is a timer in the macro queue. Execute it and print out 5resolve(6)No longer enforced;
  9. The lastconsole.log(p)Print out thePromise{<resolved>: 1};

25. Code output result

const async1 = async() = > {console.log('async1');
  setTimeout(() = > {
    console.log('timer1')},2000)
  await new Promise(resolve= > {
    console.log('promise1')})console.log('async1 end')
  return 'async1 success'
} 
console.log('script start');
async1().then(res= > console.log(res));
console.log('script end');
Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .catch(4)
  .then(res= > console.log(res))
setTimeout(() = > {
  console.log('timer2')},1000)
Copy the code

The output is as follows:

script start
async1
promise1
script end
1
timer2
timer1
Copy the code

The code execution process is as follows:

  1. To execute the synchronization tape first, print script start;
  2. Add timer timer1 to the macro task queue when encountered;
  3. (promise1) (promise1) (promise1) (promise1) (promise1) (promise1) (Promise1) (Promise1)
  4. Then execute the synchronization code and print the script end;
  5. Continue with the following Promise,.then, and.catch, expecting a function as the argument, where a number is passed, so value penetration occurs, passing the value of resolve(1) to the last then, printing out 1 directly;
  6. When the second timer is encountered, it is added to the microtask queue to execute the microtask queue. The two timers are executed in sequence. However, due to the time of the timer, timer2 is printed after two seconds, and Timer1 is printed after four seconds.

26. Code output result

const p1 = new Promise((resolve) = > {
  setTimeout(() = > {
    resolve('resolve3');
    console.log('timer1')},0)
  resolve('resovle1');
  resolve('resolve2');
}).then(res= > {
  console.log(res)  // resolve1
  setTimeout(() = > {
    console.log(p1)
  }, 1000)
}).finally(res= > {
  console.log('finally', res)
})
Copy the code

The execution result is as follows:

resolve1
finally  undefined
timer1
Promise{<resolved>: undefined}
Copy the code

Note that p1 printed by the last timer is actually the return value of.finally. We know that the return value of.finally is the return value of the previous Promise if no error is thrown. In this case, the last Promise is.then(), But this.then() does not return a value, so the Promise printed by P1 will be undefined, and if a return 1 is added below the timer, the value will become 1.

27. Code output result

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')})})Copy the code

The output is as follows:

1
7
6
8
2
4
3
5
9
11
10
12
Copy the code

(1) The first round of event cycle process analysis is as follows:

  • The whole script enters the main thread as the first macro task, encounteredconsole.log, output 1.
  • encountersetTimeout, whose callback function is distributed to the macro task Event Queue. Put down tosetTimeout1.
  • encounterprocess.nextTick(), whose callback function is distributed to the microtask Event Queue. Remember toprocess1.
  • encounterPromise.new PromiseExecute directly, output 7.thenIs distributed to the microtask Event Queue. Remember tothen1.
  • Meet againsetTimeout, its callback function is distributed to the macro task Event Queue, denoted assetTimeout2.
Macro task Event Queue Microtask Event Queue
setTimeout1 process1
setTimeout2 then1

The above table shows the Event queues at the end of the macro task of the first round of Event loop, at which point 1 and 7 have been output. Two microtasks, process1 and THEN1, were discovered:

  • performprocess1, output 6.
  • performthen1, output 8.

The first round of the event loop is officially over. The result of this round is output 1,7,6,8.

(2) The second round of the time loop starts with the **setTimeout1** macro task:

  • First, output 2. And then I came acrossprocess.nextTick(), and distribute it to the micro-task Event Queue, denoted asprocess2.
  • new PromiseImmediately execute output 4,thenAlso distributed to the microtask Event Queue, denoted asthen2.
Macro task Event Queue Microtask Event Queue
setTimeout2 process2
then2

The second round of event loop macro tasks is completed, and two microtasks, process2 and then2, are found to execute:

  • The output of 3.
  • The output of 5.

The second round of event loop ends, and the second round outputs 2,4,3,5.

(3) The third round of the event loop begins. At this point, only setTimeout2 is left.

  • Output 9 directly.
  • willprocess.nextTick()To the microtask Event Queue. Remember toprocess3.
  • Direct executionnew Promise, output 11.
  • willthenTo the microtask Event Queue, denoted asthen3.
Macro task Event Queue Microtask Event Queue
process3
then3

The third round of event loop macro task execution completes, executing two microtasks process3 and then3:

  • The output of 10.
  • The output of 12.

9,11,10,12 is displayed in the third round of the event loop.

The whole code, three event loops, the complete output is 1,7,6,8,2,4,3,5,9,11,10,12.

28. Code output result

console.log(1)

setTimeout(() = > {
  console.log(2)})new Promise(resolve= >  {
  console.log(3)
  resolve(4)
}).then(d= > console.log(d))

setTimeout(() = > {
  console.log(5)
  new Promise(resolve= >  {
    resolve(6)
  }).then(d= > console.log(d))
})

setTimeout(() = > {
  console.log(7)})console.log(8)
Copy the code

The output is as follows:

1
3
8
4
2
5
6
7
Copy the code

The code execution process is as follows:

  1. First, execute the script code and print 1.
  2. When the first timer is encountered, join the macro task queue.
  3. If a Promise is encountered, execute the code and print 3. If a resolve is encountered, add it to the microtask queue.
  4. When the second timer is encountered, join the macro task queue.
  5. When the third timer is encountered, it is added to the macro task queue.
  6. Continue to execute the script code, print out 8, the first round of execution is complete;
  7. Execute the microtask queue and print the resolve result of the first Promise: 4;
  8. Start the macro task queue, execute the first timer, print 2;
  9. If a Promise is encountered, print 6 first. If a resolve is encountered, add it to the microtask queue.
  10. Execute the microtask queue and print out 6;
  11. Execute the last timer in the macro task queue and print 7.

29. Code output result

console.log(1);
    
setTimeout(() = > {
  console.log(2);
  Promise.resolve().then(() = > {
    console.log(3)}); });new Promise((resolve, reject) = > {
  console.log(4)
  resolve(5)
}).then((data) = > {
  console.log(data);
})

setTimeout(() = > {
  console.log(6);
})

console.log(7);
Copy the code

The output of the code is as follows:

1
4
7
5
2
3
6
Copy the code

The code execution process is as follows:

  1. First execute scrip code and print out 1;
  2. When the first timer setTimeout is encountered, add it to the macro task queue.
  3. If a Promise is encountered, execute the synchronization code and print out 4. If a resolve is encountered, add it to the microtask queue.
  4. When the second timer setTimeout is encountered, add it to the red task queue.
  5. Execute the script code, print out 7, so the first round of execution is complete;
  6. Specify the code in the microtask queue and print the result of resolve: 5;
  7. Execute the first timer setTimeout in the macro task, first printing 2, then encountering promise.resolve ().then(), adding it to the microtask queue;
  8. After executing the macro task, start executing the microtask queue and print out 3;
  9. The second timer in the macro task queue continues, printing 6.

30. Code output result

Promise.resolve().then(() = > {
    console.log('1');
    throw 'Error';
}).then(() = > {
    console.log('2');
}).catch(() = > {
    console.log('3');
    throw 'Error';
}).then(() = > {
    console.log('4');
}).catch(() = > {
    console.log('5');
}).then(() = > {
    console.log('6');
});
Copy the code

The execution result is as follows:

1 
3 
5 
6
Copy the code

In this case, we need to know that, in either a thne or a catch, if the throw throws an error, it is caught by the catch, and if no error is thrown, it is continued by the “then”.

31. Code output result

setTimeout(function () {
  console.log(1);
}, 100);

new Promise(function (resolve) {
  console.log(2);
  resolve();
  console.log(3);
}).then(function () {
  console.log(4);
  new Promise((resove, reject) = > {
    console.log(5);
    setTimeout(() = >  {
      console.log(6);
    }, 10); })});console.log(7);
console.log(8);
Copy the code

The output is:

2
3
7
8
4
5
6
1
Copy the code

The code execution process is as follows:

  1. The timer is first encountered and added to the macro task queue.
  2. If you encounter a Promise, run the sync code and print out 2. If you encounter a resolve, add it to the microtask queue and print out 3.
  3. Continue to execute the code in script, print out 7 and 8, so the first round of code execution is complete;
  4. When executing the code in the microtask queue, first print out 4. If a Promise is encountered, execute the synchronization code in it and print out 5. When a timer is encountered, add it to the macro task queue.
  5. Execute the code in the macro task queue. Here we need to notice that the first timer is 100ms and the second timer is 10ms, so execute the second timer first and print 6.
  6. In this case, the microtask queue is empty, the macro task queue continues to execute, and 1 is printed.

So once we’re done with this problem, we need to be careful that the time of each timer, not all timers are 0.

Second, this

1. Code output

function foo() {
  console.log( this.a );
}

function doFoo() {
  foo();
}

var obj = {
  a: 1.doFoo: doFoo
};

var a = 2; 
obj.doFoo()
Copy the code

Output: 2

In Javascript, this refers to the current object at the time the function is executed. When foo is executed, the execution environment is the doFoo function, and the execution environment is global. So, this in foo is pointing to window, so it prints 2.

2. Code output

var a = 10
var obj = {
  a: 20.say: () = > {
    console.log(this.a)
  }
}
obj.say() 

var anotherObj = { a: 30 } 
obj.say.apply(anotherObj) 
Copy the code

Output: 10 10

As we know, the arrow function is not bound to this, its this comes from the context of its original parent, so it will first print the global a value of 10. Now, even though we have the say method pointing to another object, that doesn’t change the property of the arrow function. Its this is still global, so it still prints 10.

However, if it is a normal function, the result is completely different:

var a = 10  
var obj = {  
  a: 20.say(){
    console.log(this.a)  
  }  
}  
obj.say()   
var anotherObj={a:30}   
obj.say.apply(anotherObj)
Copy the code

Output: 20 30

In this case, the “this” in the “say” method points to the object in which it is located, and the value of a is printed.

3. Code output

function a() {
  console.log(this);
}
a.call(null);
Copy the code

Print the result: the window object

According to the ECMAScript262 specification, the call method will take the global object (the window object in the browser) as the value of this if the first argument passed in is null or undefined. So, whether null or undefined is passed, this is the global object window. So, on the browser, the answer is to output the Window object.

Note that in strict mode, NULL is null and undefined is undefined:

'use strict';

function a() {
    console.log(this);
}
a.call(null); // null
a.call(undefined); // undefined
Copy the code

4. Code output

var obj = { 
  name : 'cuggz'.fun : function(){ 
    console.log(this.name); 
  } 
} 
obj.fun()     // cuggz
new obj.fun() // undefined
Copy the code

When we use the new constructor, this refers to the global window.

6. Code output

var obj = {
   say: function() {
     var f1 = () = >  {
       console.log("1111".this);
     }
     f1();
   },
   pro: {
     getPro:() = >  {
        console.log(this); }}}var o = obj.say;
o();
obj.say();
obj.pro.getPro();
Copy the code

Output results:

1111 windowobject1111Object objwindowobjectCopy the code

Resolution:

  1. O (), o is executed globally, f1 is the arrow function, it’s not bound to this, its this refers to its parent’s this, its parent’s say refers to the global scope, so it prints out window;
  2. Obj.say (), whoever calls say refers to this in say, so this refers to an obj object;
  3. Obj.pro.getpro (), we know that the arrow function is not bound to this, getPro is in pro, and objects do not constitute a separate scope, so the arrow function’s this refers to the global scope window.

7. Code output

var myObject = {
    foo: "bar".func: function() {
        var self = this;
        console.log(this.foo);  
        console.log(self.foo);  
        (function() {
            console.log(this.foo);  
            console.log(self.foo);  
        }());
    }
};
myObject.func();
Copy the code

Output: bar bar undefined bar

Resolution:

  1. First of all, func is called by myObject. This refers to myObject. And because var self = this; So self points to myObject.
  2. This instant-execution anonymous function expression is called by window, and this refers to window. The scope for executing the anonymous function immediately is in the scope of myObject.func. The self variable is not found in this scope. Looking up the scope chain, I find self pointing to myObject.

8. Code output problem

window.number = 2;
var obj = {
 number: 3.db1: (function(){
   console.log(this);
   this.number *= 4;
   return function(){
     console.log(this);
     this.number *= 5; }}}) ()var db1 = obj.db1;
db1();
obj.db1();
console.log(obj.number);     / / 15
console.log(window.number);  / / 40
Copy the code

This question is a little confusing for you to see, but in fact it is to examine what this refers to:

  1. When db1() is executed, this refers to the global scope, so window.number * 4 = 8, and then executes the anonymous function, so window.number * 5 = 40;
  2. Perform obj. Db1 (); Numer * 5 = 15, this refers to the obj object and executes the anonymous function.

9. Code output

var length = 10;
function fn() {
    console.log(this.length);
}
 
var obj = {
  length: 5.method: function(fn) {
    fn();
    arguments[0]();
  }
};
 
obj.method(fn, 1);
Copy the code

Output: 10 2

Resolution:

  1. The first time fn() is executed, this points to the window object and prints 10.
  2. The second execution of Arguments0 is equivalent to arguments calling the method. This refers to arguments, and two arguments are passed, so the output has length 2.

10. Code output

var a = 1;
function printA(){
  console.log(this.a);
}
var obj={
  a:2.foo:printA,
  bar:function(){
    printA();
  }
}

obj.foo(); / / 2
obj.bar(); / / 1
var foo = obj.foo;
foo(); / / 1
Copy the code

Output: 2 1 1

Resolution:

  1. Obj.foo (), foo’s this points to an obj object, so a will print 2;
  2. Bar (), printA is executed in the bar method, so printA this refers to window, so it will print 1;
  3. Foo (), foo is executed in a global object, so this refers to window, so it prints 1;

11. Code output

var x = 3;
var y = 4;
var obj = {
    x: 1.y: 6.getX: function() {
        var x = 5;
        return function() {
            return this.x; } (); },getY: function() {
        var y = 7;
        return this.y; }}console.log(obj.getX()) / / 3
console.log(obj.getY()) / / 6
Copy the code

Output: 3 6

Resolution:

  1. We know that the anonymous function this points to the global object, so this points to window, and it prints 3;
  2. GetY is called by obj, so this refers to an obj object and prints 6.

12. Code output

 var a = 10; 
 var obt = { 
   a: 20.fn: function(){ 
     var a = 30; 
     console.log(this.a)
   } 
 }
 obt.fn();  / / 20
 obt.fn.call(); / / 10
 (obt.fn)(); / / 20
Copy the code

Output: 20 10 20

Resolution:

  1. Obt.fn (), fn is called by obt, so this points to the obt object and prints 20;
  2. Obt.fn.call (), where the call argument is null with nothing written, we know that if the call argument is undefined or null, then this will refer to the global object this, so it will print 10;
  3. (obt.fn)(), where the parentheses are used to change the order in which the expression is operated. This is equivalent to obt.fn(), so it prints 20;

13. Code output

function a(xx){
  this.x = xx;
  return this
};
var x = a(5);
var y = a(6);

console.log(x.x)  // undefined
console.log(y.x)  / / 6
Copy the code

Output: undefined 6

Resolution:

  1. Var x = a(5); var x = a(5); var x = a(5); Window.x = window.x = window.x = window.x = window.x = window.x Var x = a(5); var x = a(5); var x = a(5); Then execute console.log(x.x), which is console.log(window.x), and the window object has no x property, so undefined is printed.
  2. When you point to y.x, you assign the global variable x to 6, so 6 is printed.

14. Code output result

function foo(something){
    this.a = something
}

var obj1 = {
    foo: foo
}

var obj2 = {}

obj1.foo(2); 
console.log(obj1.a); / / 2

obj1.foo.call(obj2, 3);
console.log(obj2.a); / / 3

var bar = new obj1.foo(4)
console.log(obj1.a); / / 2
console.log(bar.a); / / 4
Copy the code

Output: 2 3 2 4

Resolution:

  1. First, do obj1.foo(2); The a attribute is added to obj with a value of 2. A, a is called from obj1 on the right, so this points to obj and prints out 2;
  2. Call (obj1.foo.call(obj2, 3)) will point foo’s this to obj2, so it will print 3;
  3. Obj1.a will print out 2;
  4. The new binding has a higher priority than the implicit binding, so it will print 4.

15. Code output result

function foo(something){
    this.a = something
}

var obj1 = {}

var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a); / / 2

var baz = new bar(3);
console.log(obj1.a); / / 2
console.log(baz.a); / / 3
Copy the code

Output: 2, 2, 3

This question is similar to the previous one, mainly examining the priority of this binding. Keep the following conclusions in mind: The priority of this binding is new binding > explicit binding > Implicit binding > Default binding.

Scope & variable promotion & closure

1. Code output

(function(){
   var x = y = 1; }) ();var z;

console.log(y); / / 1
console.log(z); // undefined
console.log(x); // Uncaught ReferenceError: x is not defined
Copy the code

Var x = y = 1; Actually here is from right to left, executed first y = 1, because the y don’t use the var statement, so it is a global variable, and then the next step is to assign a value to x, y speak a global variable assignment to a local variable, in the end, is a local variable x, y is a global variable, so the print x is an error.

2. Code output

var a, b
(function () {
   console.log(a);
   console.log(b);
   var a = (b = 3);
   console.log(a);
   console.log(b); }) ()console.log(a);
console.log(b);
Copy the code

Output results:

undefined 
undefined 
3 
3 
undefined 
3
Copy the code

If b is assigned 3, b is a global variable, and 3 is assigned to a, which is a local variable, then a is still undefined when printed.

3. Code output

var friendName = 'World';
(function() {
  if (typeof friendName === 'undefined') {
    var friendName = 'Jack';
    console.log('Goodbye ' + friendName);
  } else {
    console.log('Hello ' + friendName);
  }
})();
Copy the code

Output: Goodbye Jack

We know that in JavaScript, both Function and var are promoted, so the above code is equivalent to:

var name = 'World! ';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();
Copy the code

In this way, the answer is clear.

4. Code output

function fn1(){
  console.log('fn1')}var fn2
 
fn1()
fn2()
 
fn2 = function() {
  console.log('fn2')
}
 
fn2()
Copy the code

Output results:

fn1
Uncaught TypeError: fn2 is not a function
fn2
Copy the code

Here we are also looking at variable promotion, the key is the first fn2(), fn2 is still an undefined variable, so we will report that fn2 is not a function.

5. Code output

function a() {
    var temp = 10;
    function b() {
        console.log(temp); / / 10
    }
    b();
}
a();

function a() {
    var temp = 10;
    b();
}
function b() {
    console.log(temp); Uncaught ReferenceError: temp is not defined
}
a();
Copy the code

Of the above two code sections, the first section will print normally, which should be fine. The key is the second section, which will report Uncaught ReferenceError: Temp is not defined. That’s because temp is undefined when b is executed.

6. Code output

 var a=3;
 function c(){
    alert(a);
 }
 (function(){
  var a=4; c(); }) ();Copy the code

The scope chain of variables in js is related to the context in which they are defined, and independent of execution. The execution environment only changes this, passed parameters, global variables, and so on

7. Code output problem

function fun(n, o) {
  console.log(o)
  return {
    fun: function(m){
      returnfun(m, n); }}; }var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);
Copy the code

Output results:

undefined  0  0  0
undefined  0  1  2
undefined  0  1  1
Copy the code

Here’s a problem with closures. In the case of fun, an object is returned after the call. We know that when a function is called with fewer arguments than is specified when the function is declared, all remaining parameters are set to undefined. So the console. The log (o); It’s going to print undefined. And a is the object that fun(0) returns. In other words, fun has an argument n of 0, and the object that is returned needs an argument n, and this object has no scope for n, so it continues to search for n one level up the scope, and finally finds n in fun, and n has a value of 0. Once you know that, everything else is easy, and so on.

8. Code output

f = function() {return true; }; g =function() {return false; }; (function() {   
   if(g() && [] == ! []) { f =function f() {return false; };function g() {return true;}   
   }   
})();   
console.log(f());
Copy the code

The output is false

So first of all, we’ve defined two variables, f and g, and we know that variables can be reassigned. This is an anonymous function that calls g() in the if condition. Since g() is redefined in the anonymous function, it overwrites the externally defined variable g, so it calls the internal function g and returns true. The first condition passes, and we go to the second condition.

The second condition is [] ==! [], look first! [], in JavaScript, when used for Boolean operations, such as here, non-null references to objects are treated as true, and null references to objects are treated as false. Since this is not a null, but an array with no elements, [] is treated as true, and! The result of [] is false. When a Boolean value is used in a conditional operation, true is treated as a 1 and false as a 0. When an object participates in a condition comparison, it is evaluated. The result of the evaluation is that the array becomes a string, the result of [] is “, and “is treated as 0, so the condition is true.

Both conditions are true, so the code in the condition will be executed. F is defined without var, so it is a global variable. So, we’re going to access the external variable f through the closure, and we’re going to reassign it, and now we’re going to return false. And g doesn’t have that problem, so here’s g defined inside a function, so it doesn’t affect the outside g function. So it’s going to be false.

Iv. Prototype & Inheritance

1. Code output

function Person(name) {
    this.name = name
}
var p2 = new Person('king');
console.log(p2.__proto__) //Person.prototype
console.log(p2.__proto__.__proto__) //Object.prototype
console.log(p2.__proto__.__proto__.__proto__) // null
console.log(p2.__proto__.__proto__.__proto__.__proto__)// Null is not followed by an error
console.log(p2.__proto__.__proto__.__proto__.__proto__.__proto__)// Null is not followed by an error
console.log(p2.constructor)//Person
console.log(p2.prototype)P2 is an instance and has no prototype property
console.log(Person.constructor)//Function An empty Function
console.log(Person.prototype)// Print all the methods and properties of the person. prototype object
console.log(Person.prototype.constructor)//Person
console.log(Person.prototype.__proto__)// Object.prototype
console.log(Person.__proto__) //Function.prototype
console.log(Function.prototype.__proto__)//Object.prototype
console.log(Function.__proto__)//Function.prototype
console.log(Object.__proto__)//Function.prototype
console.log(Object.prototype.__proto__)//null
Copy the code

This deontological question examines prototypes, the basis of prototype chains, just remember.

2. Code output

// a
function Foo () {
 getName = function () {
   console.log(1);
 }
 return this;
}
// b
Foo.getName = function () {
 console.log(2);
}
// c
Foo.prototype.getName = function () {
 console.log(3);
}
// d
var getName = function () {
 console.log(4);
}
// e
function getName () {
 console.log(5);
}

Foo.getName();           / / 2
getName();               / / 4
Foo().getName();         / / 1
getName();               / / 1
new Foo.getName();       / / 2
new Foo().getName();     / / 3
new new Foo().getName(); / / 3
Copy the code

Output: 2 4 1 1 2 3 3

Resolution:

  1. Foo.getname (), Foo is a function object, and objects can have properties. B defines Foo’s getName property as a function, and prints 2;
  2. GetName () getName() getName() getName() getName() getName() getName() getName() getName();
  3. ** Foo().getName(), ** Foo().getName(), ** Foo().getName(), ** Foo().getName(); Foo().getName(), which is window.getName(), prints 1;
  4. GetName (), global getName has been reassigned, so it still prints 1;
  5. New foo.getName (), which is equivalent to new (foo.getName ()), executes foo.getName (), prints 2, and then new an instance;
  6. New Foo().getName(), which is equivalent to (new Foo()).getName(), new an instance of Foo, and then executes the instance’s getName method, but the instance itself doesn’t have this method, so go to __protot__ and look at it. Protot === foo. prototype, so output 3;
  7. New new Foo().getName(), which is equivalent to new (new Foo().getName()), as in 6 above. Print 3 first, and then new an instance of new Foo().getName().

3. Code output

var F = function() {};
Object.prototype.a = function() {
  console.log('a');
};
Function.prototype.b = function() {
  console.log('b');
}
var f = new F();
f.a();
f.b();
F.a();
F.b()
Copy the code

Output results:

a
Uncaught TypeError: f.b is not a function
a
b
Copy the code

Resolution:

  1. F is not an instance of Function because it is not a constructor. It calls the related properties and methods on the Function prototype chain and can only access the Object prototype chain. So f.a() will print a, and f.b() will give an error.
  2. F is a constructor, and F is an instance of the constructor Function. F instanceof Object === true, F instanceof Function === true, F instanceof Function === true So F.a() outputs A, and F.b() outputs B.

4. Code output

function Foo(){
    Foo.a = function(){
        console.log(1);
    }
    this.a = function(){
        console.log(2)
    }
}

Foo.prototype.a = function(){
    console.log(3);
}

Foo.a = function(){
    console.log(4);
}

Foo.a();
let obj = new Foo();
obj.a();
Foo.a();
Copy the code

Output: 4 2 1

Resolution:

  1. Foo.a() this is the static method a that calls Foo. Even though Foo has a higher priority property method a, Foo is not called at this point, so it prints the result of Foo’s static method a: 4
  2. let obj = new Foo(); The new method is used to call the function, and the function instance object is returned. At this point, the property methods inside the function Foo are initialized, and the prototype chain is established.
  3. obj.a() ; Call method A on an obj instance, which currently has two A methods: an internal property method and a prototype method. When both exist, look for ownProperty first, and if not, look for ownProperty on the prototype chain, so call a on the instance and output: 2
  4. Foo.a() ; Step 2 shows that the property method inside the Foo function is initialized, overriding the static method of the same name, so output: 1

5. Code output

function Dog() {
  this.name = 'puppy'
}
Dog.prototype.bark = () = > {
  console.log('woof! woof! ')}const dog = new Dog()
console.log(Dog.prototype.constructor === Dog && dog.constructor === Dog && dog instanceof Dog)
Copy the code

The output is true

Analytic: because the constructor is the property on the prototype, so t constructor is actually point to t prototype. The constructor; The constructor attribute points to the constructor. Instanceof checks whether the type is on the prototype chain of the instance.

It is easy to overlook that constructor is a property of Prototype. (1) Constructor (); (2) Instanceof (); (3) Constructor (); (4); Instanceof, on the other hand, is more loose and returns true as long as the type being tested is on the prototype chain.

6. Code output

var A = {n: 4399};
var B =  function(){this.n = 9999};
var C =  function(){var n = 8888};
B.prototype = A;
C.prototype = A;
var b = new B();
var c = new C();
A.n++
console.log(b.n);
console.log(c.n);
Copy the code

Output: 9999 4400

Resolution:

  1. Var b = new b (); var b = new b (); Inside the function this.n=9999(when this refers to b) returns the b object, which has its own n attribute, so returns 9999.
  2. Console.log (c.n), similarly, when var c = new c (), the c object has no property of its own, look up, find the n property on the prototype, because A.n++(where n in object A is 4400), so return 4400.

7. Code output problem

function A(){}function B(a){this.a = a;
}
function C(a){if(a){
thisA = a; } } A.prototype.a =1;
B.prototype.a = 1;
C.prototype.a = 1;
 
console.log(new A().a);
console.log(new B().a);
console.log(new C(2).a);
Copy the code

Output: 1 undefined 2

Resolution:

  1. Console.log (new A().a), new A() is an object created by the constructor. It does not have A property of its own, so it goes to its stereotype.
  2. Console.log (new B().a), ew B() is the object created for the constructor, which takes a parameter, but the object is not passed, so the output value is undefined;
  3. Console. log(new C(2).a), new C() is the object created by the constructor, which takes a and passes the argument 2.

8 Code output problem

function Parent() {
    this.a = 1;
    this.b = [1.2.this.a];
    this.c = { demo: 5 };
    this.show = function () {
        console.log(this.a , this.b , this.c.demo ); }}function Child() {
    this.a = 2;
    this.change = function () {
        this.b.push(this.a);
        this.a = this.b.length;
        this.c.demo = this.a++;
    }
}

Child.prototype = new Parent();
var parent = new Parent();
var child1 = new Child();
var child2 = new Child();
child1.a = 11;
child2.a = 12;
parent.show();
child1.show();
child2.show();
child1.change();
child2.change();
parent.show();
child1.show();
child2.show();
Copy the code

Output results:

parent.show(); / / 1 5 [1, 2, 1]

child1.show(); 11 [1, 2, 1] / / 5
child2.show(); 12 [1, 2, 1] / / 5

parent.show(); / / 1 5 [1, 2, 1]

child1.show(); / / 5,2,1,11,12 [1]

child2.show(); / / 6,2,1,11,12 [1] 5
Copy the code

This topic is worth god emperor, he involves a lot of knowledge points, such as this point, prototype, prototype chain, class inheritance, data type and so on.

Resolution:

  1. Parent-.show (), which gets the desired value directly, is nothing to say;
  2. Child1. The show (),ChildThe constructor of is supposed to point toChildOf, and they explicitly writeChildClass’s prototype object points toParentClass, which requires attentionChild.prototypePoints to theParentAn instance of theparent“Rather than pointingParentThis class.
  3. Child2. show(), there’s nothing to say about this;
  4. The parent. The show (),parentIs aParentClass,Child.prorotypePoints to theParentClass, the two do not affect each other in the heap memory, so the above operations do not affectparentInstance, so the output doesn’t change;
  5. Child1. The show (),child1To perform thechange()What has changed since then?
  • This. P. ush (enclosing a),Because of the dynamic pointing nature of this, this.b will point toChild.prototypeOn thebArray,this.a will point tochild1theaProperty, soChild.prototype.bInto a * * * *,2,1,11 [1];
  • A = this.b.long; a = this.b.long; a = this.b.long;
  • Enclosing c.d emo = this. +,Due to thechild1It doesn’tcThis property, so herethis.cWill pointChild.prototype.c.this.aA value of4, is the primitive type, so the assignment operation assigns a value directly,Child.prototype.c.demoAs the result of the4And thethis.aThen it increases to5(4 + 1 = 5).
  1. child2To perform thechange()Method, andchild2andchild1All isChildClass, so their stereotype chain points to the same stereotype objectChild.prototypeWhich is the same thingparentInstance, sochild2.change()All statements that affect the prototype object inchild1The final output of.
  • This. P. ush (enclosing a),Because of the dynamic pointing nature of this, this.b will point toChild.prototypeOn thebArray,this.a will point tochild2theaProperty, soChild.prototype.bInto a * * * *,2,1,11,12 [1];
  • A = this.b.long; a = this.b.long; a = this.b.long;
  • Enclosing c.d emo = this. +,Due to thechild2It doesn’tcThis property, so herethis.cWill pointChild.prototype.c, the execution result isChild.prototype.c.demoThe value of achild2.aThe value of the5And thechild2.aAnd then it increases to zero6(5 + 1 = 6).

9. Code output

function SuperType(){
    this.property = true;
}

SuperType.prototype.getSuperValue = function(){
    return this.property;
};

function SubType(){
    this.subproperty = false;
}

SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
    return this.subproperty;
};

var instance = new SubType();
console.log(instance.getSuperValue());
Copy the code

The output is true

SubType inherits from SuperType, essentially overwriting SubType’s prototype object and replacing it with an instance of the new type. The prototype for SubType has been overridden so that instance. Constructor points to SuperType. The details are as follows:

Write at the end:

Thank you for your patience in reading this long article. Read here, whether have a little harvest? I have to say, these interview questions are really a test of people’s basic JavaScript ability, especially the prototype and inheritance related questions, too convoluted, worth careful study!

Recently, the author is busy with graduation thesis, may update will be relatively slow, but also hope you forgive me.

If you found this article helpful, please give it a like.