directory
- preface
- The first question
- The second question
- Variable declaration promotion
- Functional expression
- Variable declaration promotion
- The third question
- The fourth question
- 5 q
- Q 6
- The return value of the constructor
- The return value of the constructor
- 7 q
- The last
preface
Years ago has just left, I once had a job interview questions, under the share this topic is me out of the front facet of a set of questions in the last question, used to assessment the interviewer JavaScript comprehensive ability, it is a pity that so far, nearly two years, almost no one can completely right, how hard is not only because most of the interviewer too despised him.
The title is 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); } // Write the following output: foo.getName (); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); new new Foo().getName();Copy the code
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 (); //2 getName(); //4 Foo().getName(); //1 getName(); //1 new Foo.getName(); //2 new Foo().getName(); //3 new new Foo().getName(); / / 3Copy the code
This problem is my synthesis before the development experience and encountered all kinds of JS pit pooled. This topic involves a variety of topics, including variable definition promotion, this pointer pointing, operator priority, stereotype, inheritance, global variable pollution, object attributes and stereotype attribute priority, etc.
There are seven questions in this question.
The first question
First we define a function called Foo, then we create a static property called getName to store an anonymous function for Foo, and then we create a new anonymous function called getName for Foo’s prototype object. We then create a function called getName using function variable expressions, and finally declare a function called getName.
The Foo. GetName of the first question is, of course, a static property stored on Foo, which is, of course, 2, nothing to say.
The second question
Second, call the getName function directly. 1, 2, 3: getName = getName = getName = getName = getName = getName = getName = getName = getName Countless candidates answered 5 to this question. There are two holes 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:
console.log('x' in window); //true var x;Copy the code
x = 0;Copy the code
When the code executes, the JS engine will elevate the declaration statement to the top of the code, changing it to:
var x; console.log('x' in window); //true x = 0;Copy the code
Functional expression
Var getName and function getName are declarations. The difference is that var getName is a function expression and function getName is a function declaration. JS on a variety of functions to create the way can see most people will do the wrong classic JS closure interview questions this article has detailed explanation.
The biggest problem with function expressions is that JS will split this code into two lines of code to execute separately.
For example:
console.log(x); Function x(){} var x=1; function x(){}Copy the code
Var x=1; var x=1; And x = 1; Two lines, var x; Function x(){} function x(){}
var x;
function x(){}
console.log(x);
x=1;Copy the code
So the final x of the function declaration overrides the x of the variable declaration, and the log output is the x function.
Similarly, the code in the original problem is finally executed with:
function Foo() { getName = function () { alert (1); }; return this; } var getName; Function getName() {alert (5); } Foo. GetName = function () {alert (2); }; Foo.prototype.getName = function () { alert (3); }; getName = function () { alert (4); }; // The final assignment overrides the function getName declaration getName(); // Final output 4Copy the code
The third question
Foo().getName(); Function Foo is executed, and then the getName property function of the return value object of function Foo is called.
GetName = function () {alert (1); }; GetName is a function assignment statement. Note that it does not have a var declaration, so look for the getName variable in the scope of the current Foo function. Alert (4) function(){alert(1)} function(){alert(1)} function(){alert(1)} function(){alert(1)}
This is actually changing the getName function in the outer scope.
Note: If it is still not found, it will look up to the Window object. If there is no getName attribute in the Window object, it will create a getName variable in the window object.
Foo then returns this, and JS’s this problem has already been covered in a number of articles in the blogosphere.
Simply put, the reference to this is determined by how the function is called. And the direct call here, this refers to the window object.
The Foo function returns the window object, which is equivalent to window.getName(), and the getName in window has been changed to alert(1), so the final output is 1
Here two knowledge points are investigated, one is the variable scope problem, the other is the this pointing problem.
The fourth question
Call getName directly, equivalent to window.getName(), because this variable has been modified by Foo, and the result is the same as in question 3, 1
5 q
New foo.getName (); , here is to examine the js operator priority problem.
Js operator priority:
Review images
Reference link: developer.mozilla.org/zh-CN/docs/…
Point (.) can be obtained by checking the above table. The priority of the new operation is higher than that of the new operation, thus equivalent to:
new (Foo.getName)();Copy the code
So the getName function is actually executed as a constructor, and 2 pops up.
Q 6
New Foo().getname () = Foo()
(new Foo()).getName()Copy the code
Function Foo is executed first, and Foo, as a constructor, returns a value.
The return value of the constructor
In traditional languages, constructors should have no return value, and the return value actually executed is the constructor’s instantiation object.
In JS constructors may or may not have a return value.
1. If no value is returned, the instantiated object is returned as in other languages.
Review images
2. If there is a return value, check whether the return value is a reference type. If is a reference type, such as basic types (string, number, Boolean, null, and undefined) with no return values are the same, the actual return to instantiate the object.
Review images
3. If the return value is a reference type, the actual return value is that reference type.
Review images
In the original problem, we return this, which in the constructor represents the currently instantiated object, so finally Foo returns the instantiated object.
We call getName of the instantiated object, because we didn’t add any properties to the Foo constructor. We look for getName in the prototype of the current object and find it.
So the final output is 3.
7 q
New new Foo().getName(); Again, it’s operator priority.
The final actual execution is:
new ((new Foo()).getName)();Copy the code
Initialize Foo’s instantiation object, and then new again with the getName function on its prototype as a constructor.
The final result is 3
=== Updated on March 23, 2016 ===
Here is a comment by @Yu Minghao that explains question 7 in more detail:
This is (new Foo()).getName(), but it has nothing to do with the fact that parentheses take precedence over member access. In fact, member access has the highest precedence, so.getName is executed first, but new Foo() can be interpreted as two operations when the left value is evaluated: New takes arguments (that is, new Foo()) and a function call (that is, Foo() is evaluated before new). New takes precedence over function calls, so new Foo() or an instance object of class Foo is executed, and.getName is accessed.
The last
In terms of the answers, 100% of the first questions can be answered correctly, only about 50% of the second questions can be answered correctly, the third questions can be answered correctly, and the fourth questions are very, very few. Most people with one or two years of work experience should be absolutely correct.
Can only say that some people are too impatient too despise, hope we understand some features of JS through this article.
And I wish you all courage and prudence in the New Year job interview, play your best and find an ideal job.
The original link: http://www.cnblogs.com/xxcanghai/p/5189353.html