Directory
- Objective
- First question
- Second question
- Variable declaration Promotion
- function expression
- Third question
- Question Four
- Question Five
- Question Six
- The return value of the constructor function
- Seventh question
- At last
Objective
Years ago just quit, share the next I have been out of an interview problem, this question is my one set of front-end interview questions in the final question, used to assess the overall ability of the interviewer's JavaScript, unfortunately so far nearly two years, almost no one can fully correct, It's not that hard just because most interviewers despise him too much.
The topics are as follows:
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);} Please write out the following output results: Foo.getname (); GetName (); Foo (). GetName (); GetName (); new Foo.getname (); new Foo (). GetName (); New New Foo (). GetName ();
The answer is:
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);} Answer: Foo.getname ();//2getname ();//4foo (). GetName ();//1getname ();//1new foo.getname ();//2new Foo (). GetName ();// 3new new Foo (). GetName ();//3
This question is my synthesis prior to the development experience and encountered JS various pits into the collection. This topic involves a number of knowledge points, including variable definition elevation, this pointer, operator precedence, prototype, inheritance, global variable pollution, object properties and prototype attribute precedence, and so on.
This question contains 7 small questions, respectively.
First question
First to see what the upper part of the problem did, first defined a function called Foo, and then for Foo to create a static property called GetName stored an anonymous function, and then a prototype of Foo's object created a new anonymous function called GetName. It then creates a getname function with a function variable expression, and finally declares a function called GetName.
The first question of Foo.getname is naturally the static property stored on the Access Foo function, which is naturally 2, nothing to say.
Second question
Second question, call the getName function directly. Since it is a direct call, it is not related to 1 2 3 to access the function called GetName in the scope of the current above. The question has been answered by countless interviewees as 5. There are two pits here, one is the variable declaration promotion, and the other is the function expression.
Variable declaration Promotion
That is, all declared variables or declared functions are promoted to the top of the current function.
For example, the following code:
Console.log (' x ' in window);//truevar x;
x = 0;
When the code executes, the JS engine promotes the declaration statement to the top of the code and becomes:
var x;console.log (' X ' in window);//truex = 0;
function expression
var getName and function GetName are declaration statements, except that var getName is a function expression, and function GetName is a functional declaration. About JS in the various functions to create a way to see most people will do wrong classic JS closed-face question this article has detailed description.
The biggest problem with function expressions is that JS splits this code into two lines of code to execute separately.
For example, the following code:
Console.log (x);//output: function X () {}var x=1;function x () {}
The code that is actually executed is to break the Var x=1 into var x, and x = 1, two lines, and then the var x; and function X () {} Two rows to the top: /c4>
var x;function x () {}console.log (x); x=1;
So the final function declares an x that overrides the X,log output of the variable declaration to the X function.
In the same vein, the code in the original topic was finally executed:
function Foo () { getName = function () {alert (1);}; return this;} var getname;//only raise the variable declaration function GetName () {alert (5);} Lifting function declaration, overriding var declaration foo.getname = function () {alert (2);}; Foo.prototype.getName = function () {alert (3);}; GetName = function () {alert (4);};/ /final Assignment overrides function GetName declaration getname ();//FINAL Output 4
Third question
The third question is foo (). GetName (), executes the Foo function first, and then calls the GetName property function of the return value object of the Foo function.
The first sentence of the Foo function is getName = function () {alert (1);}; is a function assignment statement, note that it does not have a var declaration, so we first look for the getname variable within the scope of the current Foo function, No. Then to the current function scope upper layer, that is, the outer scope of the search for the getname variable, found, that is, the second question in the alert (4) function, the value of this variable is assigned to function () {alert (1)}.
The GetName function in the outer scope is actually modified here.
Note: If this is still not found, it will always look up to the Window object, and if there is no GetName property in the Window object, create a GetName variable in the Window object.
After the Foo function return value is this, and JS This problem blog Park has a lot of article introduction, here no more say.
In a nutshell, the point of this is determined by the way in which the function is called. Here, the direct invocation method, this points to the Window object.
The Foo function returns the Window object, which is equivalent to executing window.getname (), while the GetName in window has been modified to alert (1), so it will eventually output 1
Here we examine two knowledge points, one is the variable scope problem, and the other is this point problem.
Question Four
Call the GetName function directly, equivalent to window.getname (), because this variable has been modified by the Foo function, the result is the same as the third question, 1
Question Five
Ask new Foo.getname (); Here is the JS operator precedence problem.
JS Operator Precedence:
Reference Link: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
By checking the table you can tell that the point (.) has a higher priority than the new operation, which is equivalent to:
New (Foo.getname) ();
So the GetName function is actually executed as a constructor, so it pops up 2.
Question Six
Ask new Foo (). GetName (), first look at operator precedence brackets above new, actually executed as
(New Foo ()). GetName ()
The Foo function is executed first, and Foo has a return value as the constructor, so it is necessary to explain the constructor return value problem in JS.
The return value of the constructor function
In a traditional language, a constructor should not have a return value, and the actual execution of the return value is the instantiated object of this constructor.
In JS, the constructor can have a return value or not.
1. No return value returns the instantiated object in the same way as other languages.
2. If there is a return value, check if the return value is a reference type. If the non-reference type, such as the base type (string,number,boolean,null,undefined), is the same as the no return value, which actually returns its instantiated object.
3. If the return value is a reference type, the actual return value is the reference type.
In the original title, this is returned, and this represents the current instantiation object in the constructor, and the final Foo function returns the instantiated object.
The GetName function of the instantiated object is then called, because no attributes are added to the instantiated object in the Foo constructor, and a getname is found in the prototype object (prototype) of the current object.
The final output is 3.
Seventh question
Seventh question, new New Foo (). GetName (); same as operator precedence.
The final actual execution is:
New ((New Foo ()). GetName) ();
Initialize Foo's instantiation object first, and then new again with the GetName function on its prototype as the constructor.
The final result is 3.
===2016 year March 23 update = = =
This quote @ Yu Minghao's comment explains the 7th question in more detail:
This is really (new Foo ()). GetName (), but with parentheses precedence over member access It's okay, actually the member accesses are the highest priority, so the first one executes the. GetName, but the new Foo () when the left value is taken Can be understood as two operations: New with parameters (that is, new Foo ()) and function calls (that is, the first foo () after the value of new), and the priority of the new parameter is higher than the function call, so first executed the new Foo (), or the Foo class instance object, and then the member access. GE Tname.
At last
As far as the answer is concerned, the first 100% can be answered correctly, the second question is probably only 50% correct rate, the third question can answer the correct is not much, the fourth question again correct is very very few. In fact, this problem does not have too many tricky to use, are some of the scenarios may encounter, and most people have 1 to 2 years of work experience should be completely correct.
Can only say that there are some people too impatient too contempt, I hope that we understand some features of JS through this article.
and wish everyone in the new year to find a job interview bold but cautious, to play the best level, to find an ideal job.
Original link: http://www.cnblogs.com/xxcanghai/p/5189353.html
A front-end JS face question which is often despised by people