Front-end programmers often overlooked JavaScript face questions

topic

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();

This question is a classic is that it combines a comprehensive study of the ability of JavaScript interviewer, including the variable definition upgrade, this pointer points, operator precedence, prototype, inheritance, global variables contamination, object attributes and attribute prototype priority such knowledge, this question is also relevant in the online part of the explanation, of course, I think there is also partly explained by the defect, is not clear enough, specifically to analyze the heavy head to tail once, of course we will finally answer on the back, and put this question again and change a little higher difficulty, an improved version also placed at the end, there is a convenient reference when the interviewer a question.

First asked

Look at the upper part of this question of what to do, first define a function called Foo, and then created a static property called getName stores an anonymous function Foo, followed by prototype object to create a new Foo called getName anonymous function. And later by function variable expression creates a function getName, and finally declare a function called getName. The first is natural to ask Foo.getName access storage on the function Foo static properties, the answer is naturally 2, there is no need to explain too much, in general, the first question to know a little JS-based students who should not the problem, of course, we can use the following code to recap, to deepen understanding about.

function the User (name) {     var name = name; // private attributes this.name = name; // Properties public function getName () {// private method return name;}} User.prototype.getName = function () {/ / public methods return this.name;} User.name = 'Wscats '; // static properties user.getName = function () {// static method return this.name;} var Wscat = new User ( 'Wscats'); // instantiate

Note that the following points:

Invoke public methods, public property, we need to instantiate an object, i.e. new operator real object, the object can be instantiated constructor methods and properties, and the method is not invoked public private static methods and methods

Static methods and static properties that we do not need to instantiate can call

The private methods and properties of the object, is not accessible outside of

The second question

The second question, directly call getName function. Since it is a direct call function that is called getName access the current role of the above domain, so there should directly focus on the 4 and 5, with 123 have nothing to do. Later, of course I asked several of my colleagues, most of them answered 5. In fact, here are two pits, one variable declaration upgrade, the second is the difference between function expressions and function declarations. We look at why, refer to (1) the function declaration and function expression on Javascript in (2) variable on JavaScript upgrade.
In Javascript, there are two types of defined functions.

Function declarations

// function declaration 
function wscat (type) {
     return type === "wscat" ; 
}

Function expression

// function expression 
var oaoafly = function (type) {
     return type === "oaoafly" ; 
}

Look at the following this classic problem, and define a function called by getName function declaration and function expression of a program inside.

getName() //oaoafly
var getName = function() {
    console.log('wscat')
}
getName() //wscat
function getName() {
    console.log('oaoafly')
}
getName() //wscat

The above code looks very similar to the feeling not much difference. But in fact, the Javascript function on a "trap" is reflected in the two types Javascript function definition.

JavaScript interpreter mechanism for variable declaration is lifted exist, that is a function declaration will be promoted to the top of the scope, even write the code is written in the final surface, still it will be raised to the top.

The function is a function expression creates an assignment at runtime, and the call to wait until after the completion of the assignment expression

var getName // variables to be lifted, in this case undefined 

getName () // oaoafly function is affected by this upgrade function declaration, a function declaration while the last may be raised to the top of the 
var getName = function () { 
    the console.log ( 'wscat' ) 
} // function expression began to cover this case defined function declaration 
getName () // wscat 
function getName () { 
    the console.log ( 'oaoafly' ) 
} 
getName () // wscat performed here valued function expression

It can be decomposed into a clear difference between the nature of these two simple questions to see

var getName;
console.log(getName) //undefined
getName() //Uncaught TypeError: getName is not a function
var getName = function() {
    console.log('wscat')
}
var getName;
console.log(getName) //function getName() {console.log('oaoafly')}
getName() //oaoafly
function getName() {
    console.log('oaoafly')
}

This distinction may seem trivial, but in some cases difficult to detect and is indeed a "fatal" trap. The emergence of this trap because the nature reflected in the difference between the two types (parsing / running) to enhance the function and operation of timing. Of course, we give a summary: Javascript in function declarations and function expressions is there is a difference, and a function to enhance the function declaration in the JS parsing, so in the same scope, regardless of where the function declaration defined, this function can be called. The value of the function expression is determined at JS run time, and after the expression evaluation is completed, the function can be called. So the answer to the second question is that function declaration 4,5 4 covers the function expression

Third question

Foo().getName(); First implementation of the Foo function, and then call the return value of a function Foo object's property getName function. The first sentence of Foo function getName = function () { alert (1); };is a function assignment, note that it does not var statement, Talia current Foo looking getName function scope variables, no. Again top the current function scope, namely the outer scope to find whether they contain getName variables found, that is, the second question in the alert (4) function, the value of this variable is assigned function(){alert(1)}. Here it is actually the scope of the outer function getName changed. Note: If still not found here will always look up to the window object, if there is no getName window object attributes, you create a variable in getName window object. After the Foo function's return value is this, and JS of this issue has been a lot of articles, but here say no more. Simply put, this is determined by the point where the function is called in. Direct invocation here, this points to the window object. Foo function then returns the object window, corresponding to perform window.getName(), while the window has been modified Alert getName (1), so the final output will be 1. Here examines the two points of knowledge, a variable scope question is, is this a problem point
we can use the following code to review these two knowledge points.

var name = "Wscats"; // global variables 
the window.name = "Wscats"; // global variable 
function getName () { 
    name = "Oaoafly"; // removed into a global variable var 
    var privateName = "Stacsw" ;
     return  function () { 
        console.log ( the this ); // window 
        return privateName 
    } 
} 
var , getPrivate = getName ( "the Hello"); // course transmission parameter is a local variable, but the function which I do not accept this parameter 
console.log ( name) // Oaoafly 
console.log (getPrivate ()) // Stacs

Since there is no block-level scope JS, but the function is to produce a scope, the method of internal values define different function to directly or indirectly affect the global or local variables, private variables inside a function closures can be used to acquire, really function it is the first citizen - and on this point, this time in the function definition is not determined only when the function is performed in order to determine this point in the end who is, in fact, this final point is that calling it an object
so the third window is actually asked in the call Foo () function, so this point is the window

window.Foo().getName();
//->window.getName();

Fourth ask

GetName direct call function is equivalent to window.getName(), because this variable has been modified Foo function is executed, and then ask the same result with a third, to 1, which means that after the implementation of the global Foo's getName function to rewrite once, so the result is Foo () function to perform rewriting of the getName

Fifth ask

Q fifth new Foo.getName();visit here is the operator precedence problems JS, I think this is where the soul of this problem, but also more difficult of a problem. The following is the priority table JS operator, from highest to lowest. Refer MDN operator precedence.

 

 

 

 This question first look at priority 18 and 17 appear on new priorities, new (with the list of parameters) than the new (no parameter list) higher than a function call, with the same level of access to members
new Foo.getName();of a priority is this It is equivalent to:

new (Foo.getName)();

Priority point (18) than without new parameter list (17) a high priority

When the dot operator after another because of the parentheses (), and at that point becomes the new argument list (18), so the direct implementation of new, of course, may also have a friend who would question why the encounter () function call does not re-new it, that because the function call (17) than the new argument list (18) low priority

Members access (18) -> new argument list (18)

So here actually getName function as a constructor to execute, then pop 2.

Sixth ask

The only difference this question than a question of where Foo is in more of a parenthesis, this parentheses with brackets and we did not see it in the fifth when asked priorities are different.

(new Foo()).getName()

That here is how to judge it? First new argument list (18) with priority points (18) are at the same level, the same level, then execution order from left to right, so the first implementation of new argument list (18) and then the execution priority points (18 ), and finally the function call (17) new argument list (18) -> member access (18) -> () function call (17) there is also a little knowledge, Foo as a constructor have a return value, It is noted at the JS constructor return value.

Constructor function's return value

In traditional languages, constructors should not have a return value, the return value of this object is an instance constructor actually performed.
Function can be constructed in JS return value can not. 1, no return value is returned in other languages instantiate the object.

function Foo(name) {
    this.name = name
}
console.log(new Foo('wscats'))

 

 2, if the return value is checked the return value is a reference type. If the non-reference type, such as the basic type (String, Number, Boolean, Null, Undefined) with no return value is the same, the actual return instantiated objects.

function Foo(name) {
    this.name = name
    return 520
}
console.log(new Foo('wscats'))

 

 3, if the return value is a reference type, the return value is actually a reference type.

function Foo(name) {
    this.name = name
    return {
        age: 16
    }
}
console.log(new Foo('wscats'))

 

 The original title, because the return is this, and this in the constructor already represents the current instance of the object, eventually Foo function returns an instance of the object. After calling getName function to instantiate an object, because the Foo constructor did not add any properties to instantiate an object, the current prototype object (prototype) object to find getName function. Of course, here again expand a digression, if the constructor and prototype chains have the same method, as the following code, then the default constructor will take the public methods rather than the prototype chain, this knowledge did not show it in the original title, the back I improved version has been added.

function Foo(name) {
    this.name = name
    this.getName = function() {
        return this.name
    }
}
Foo.prototype.name = 'Oaoafly';
Foo.prototype.getName = function() {
    return 'Oaoafly'
}
console.log((new Foo('Wscats')).name) //Wscats
console.log((new Foo('Wscats')).getName()) //Wscats

Seventh ask

new new Foo().getName();The same problem is operator precedence. In fact, I've done this question think the answer is not so important, but the key to examine whether the interviewer really know what the interviewer in our study.
The final actual implementation are:

new ((new Foo()).getName)();

new argument list (18) -> new argument list (18) to initialize an instance of Foo object, then the function prototype getName as a new constructor again, so the final result is 3.

answer

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();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3

Follow-up

Follow me this question a little more difficult to increase a little bit (attach answers), want to add a public method getName inside the Foo function, for which the following problems if used on face questions that might pass rate is even lower, because big little difficulty, the addition of two pit, but to understand the principles of this question is equivalent to understand all of the above knowledge.

function Foo () {
     the this .getName = function () { 
        the console.log ( . 3 );
         return { 
            getName: getName // This is the constructor function involved in asking a sixth return value 
        } 
    }; // this is the sixth Q involved in priority public methods and prototype chain JS constructor method 
    getName = function () { 
        the console.log ( . 1 ); 
    }; 
    return  the this 
} 
Foo.getName = function () { 
    the console.log ( 2 ) ; 
}; 
Foo.prototype.getName = function() {
    console.log(6);
};
var getName = function() {
    console.log(4);
};

function getName() {
    console.log(5);
} //答案:
Foo.getName(); //2
getName(); //4
console.log(Foo())
Foo().getName(); //1
getName(); //1
new Foo.getName(); //2
new Foo().getName(); //3
//多了一问
new Foo().getName().getName(); //3 1
new new Foo().getName(); //3

 

 

 

Summary from: https://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649093762&idx=1&sn=4dbfac5c371cb88701c9479d9c9a26a0&chksm=be5bd12f892c583942d0b02d0c3ec646b9940ed1bbf7e35afc7c00c5746c5b2d4a0041b96aa7&mpshare=1&scene=1&srcid=0324TrdQzaRMoJhOPFpVyPHL&sharer_sharetime=1585033528966&sharer_shareid=17b7729bcb860dcade22b324b00552f0&key=942cf4f71d1d24ddde17706e1ac0a8f00736e44a94f55ffdff6634aa02fecb73d925a0b14aaaee42d195bdee997f933e204fcd59e47f878ae99ee3897d81ac3a41f68af1da4c6028fb98d486f31a2af9&ascene=1&uin=MTU5MDQyODczNQ%3D% 3D & devicetype = Windows + 7 & version = 62080079 & lang = zh_CN & exportkey = A1uT1985% 2FnJC% 2BiVrEAqDJCw% 3D & pass_ticket = iIdIUhHJ2ndkL% 2BkFG82WbD6SowrW7Nnvr4bvHEvFUYP1lvw7SPEdXTMaWaqCIkaW

Guess you like

Origin www.cnblogs.com/art-poet/p/12559142.html