A front-end JS face question which is often despised by people

Source: Internet
Author: User
Tags variable scope

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:

Answer

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.

A more detailed explanation of the 7th question:

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

Original link: http://www.cnblogs.com/xxcanghai/p/5189353.html

A front-end JS face question which is often despised by people

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.