Remember a classic JavaScript interview question

Recently, when I was reviewing front-end knowledge, I saw a very good JavaScript interview question. I will share it here and attach my analysis.

question


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

//请写出以下输出结果:
Foo.getName();          //第一题 ?
getName();              //第二题 ?
Foo().getName();        //第三题 ?
getName();              //第四题 ?
new Foo.getName();      //第五题 ?
new Foo().getName();    //第六题 ?
new new Foo().getName();//第七题 ?

  Think for yourself first, and see if you can analyze the first few steps. It is best to take out a piece of paper and calculate it.

  The classic of this question is that it comprehensively examines the comprehensive ability of the candidate's JavaScript, including variable definition promotion , this pointer pointing , operator precedence , prototype , inheritance , global variable pollution , object property and prototype property precedence and other knowledge.

  ps: Don’t take this kind of topic lightly. Although it is unlikely to appear in the project, few people write programs like this in business, but you can consolidate your foundation through such exercises.

  In addition, if you encounter such tedious questions during the interview, please remember that the interviewer does not require you to answer all the questions correctly, mainly to see if you understand the principles and ideas. Speaking of, it's not the main thing .



Here are some suggestions from Tencent's interviewers to students who are looking for internships now (in my opinion, they can also be used as mottos to remember):
1. " We can allow you not to, but once you do, you have to understand it deeply . "The
  interviewer can know your love from the interview, but your love needs to be reflected. That's why senior brothers remind us to try not to write on the resume for those skills that are not very proficient. For example, during the project experience, it is mentioned that a certain technology is used, but once asked about the subtleties of the technology, the answer is unclear, so the outcome of the interview may be tragic.


2. " Don't pay too much attention to the interview suggestions provided by the Internet or classmates, and be conscious of cultivating your true strength ."
  He put forward such an example: it should be said to the classmates online that Tencent's web page reconstruction must ask "optimization", so a classmate I recited "reduce the number of http" and "CDN", etc., but once asked why reducing the number of http can speed up the loading speed. To go deep, to understand the principle. He also said that the etiquette of the interview, such as standing up when the interviewer is seen, etc., they do not value.
  He said: There are two kinds of people, one is to know where they are lacking, the other is to know where they are lacking and try to change.


3. " When you encounter something you don't understand, you can talk about your ideas and your own thoughts. Maybe you can impress the interviewer "

This paragraph is from an intern interview experience

Parse


The previous chat is a bit long, but also to leave some space for everyone to think about the above topics. (Haha, in fact, it is also emotional~)

Note: For the sake of simple explanation, I will use the number of alert at the end of the function to refer to this function later.

What does the program do during the compilation phase?

  In order to better clarify the complex program, it is best to modify the program once according to the behavior of the program in the compilation phase (the execution of the problem program is omitted here, only for the problem of related function declarations):

function Foo() {
    getName = function () { alert (1); };
    return this;
}
function getName() { alert (5);}

Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
getName = function () { alert (4);};

  The biggest change here is the change in the position of function 5, which is function promotion , and function precedence.

Question one
Foo.getName();  //2

  This is a simple object property access problem. Some friends may mistake it for 3. If it getNamedoes not exist directly in Foo, it will traverse [[Prototype]]the chain, and only then will it be taken Foo.prototype.getName. (i.e. function 3)


Question two
getName();      //4

  In the analysis of the behavior of the program in the compilation phase, after function promotion, we can know that it getName()is finally assigned to function 4


Question three
Foo().getName();    //1

  First Foo()call the function Foo, so that getName()is assigned to function 1, and returns this, this this is window (in non-strict mode, and in the browser environment), which involves the default binding in this four binding principles . So, question three above can be further transformed into:

window.getName();

  Then the principle is the same as that of question 2, and function 1 is called.


Question four
getName();      //1

  The answer is the same as question 3, the principle is the same as question 2


Question five
new Foo.getName();      //2

  Here you need to know the priority of each operator (here, please analyze this problem according to the MDN table: operator priority )

  First of all new Foo, the new operator is connected to Foo. The new operator is treated as a parameterless list (priority 18), which is inferior to the . property access operator (priority 19). The property access is performed first, which is easy to understand, and a parenthesis is added here.

new (Foo.getName)();    //2

  Will be called Foo.getNameas a constructor, a normal function called as a constructor will first call the original function once, so Foo.getName()is called. (that is, function 2, the principle is the same as that of question 1)


Question six
new Foo().getName();    //3

  First of all new Foo(), the new operator is connected to Foo(), the new operator is treated as a parameter list (priority 19), which is consistent with the . property access operator (priority 19), and the level is the same, from left to right, the first encountered Who counts first.

When called Fooas a constructor, these things happen:
1. Create a new object that inherits from Foo.prototype;
2. thisBind to this new object;
3. The object returned by the constructor is new表达式the result of . Foo()returned in this program this(ie this new object)

To see clearly, let’s break down the problem once:

var newObj = new Foo();     //构造函数创建的新对象
newObj.getName();

  newObj is the new object returned by the constructor, this object will not get the properties on Foo, that is, there is no Foo.getNameproperty (function 2), but it inherits Foo.prototype( newObj.__proto__ === Foo.prototype), find getName on newObj, and find it on newObjthe prototype chain of . Finally found newObj.__proto__on , which is function 3.


Question seven
new new Foo().getName();    //3

This question looks scary, but if you already know the principles of Question 5 and Question 6, it's not a problem.

Here the second , and then the first new operator . The above program can be decomposed once:

var newObj = new Foo();
new (newObj.getName)();

The essence is Foo.prototype.getName()to call the constructor, the principle is the same as the third question.



If you think what I said is not clear, please say it and communicate together. If you think there is something wrong, please point it out.

(Original question source: A JavaScript interview question often overlooked by front-end programmers )

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324611102&siteId=291194637