Recently the group has a small partner to share two interview questions, here I talk about their understanding, nonsense said, on the first question:
var n = 10; var obj = {n: 20 function () { this . N + = 2; n *= 3; return function () { this . N *= 2; n + = 1; Console.log (N)}) (n)} var fn = obj.fn;f N (); Obj.fn () Console.log (N,OBJ.N)
In this topic, the FN property of the defined Obj object is a self-executing function, any self-executing function whose internal this pointer to the global variable window, so when defining the object obj, the global variable n is affected by the self-executing function, plus the self-executing function does not define N, So the window.n*=2 executes, then executes the window.n+=3, at which time the global variable n has been modified to 36;
Next
var fn =
These two steps are actually defined in the global space a variable FN, assigned to the FN property of obj, that is, the self-executing function, and then execute it itself, at this time because the function returned by the self-executing functions (closures) do not define N, will be the first-level scope lookup, is the global variable N, previously said, has been modified to , so at the time of execution
this. N *= 2; // 36*2=72n + = 1; // 72+1=73console.log (n)
The result of the FN () execution is print 73;
The following Obj.fn (), FN () executes as a method of obj, and its this value points to the obj itself, at which point the function returned by the execution function (the closure) THIS.N modifies the OBJ.N so that its value becomes 40, because the returned function does not define N, it will look up the first-level scope, that is, the global variable N, so n+1=73+1=74, so the print result is 74;
Then print the global variable n, the value is 74,OBJ.N the previous step, is 40.
OK, continue to the next topic:
functionFoo () {getName=function() {alert (1);} return This;} Foo.getname=function() {Alert (2);} Foo.prototype.getName=function() {Alert (3);}varGetname=function() {Alert (4);}functionGetName () {alert (5);} Foo.getname (); GetName (); Foo (). GetName (); GetName (); Newfoo.getname ();NewFoo (). GetName ();New NewFoo (). GetName ();
Start by looking at what this topic is doing: first define a foo function, then create a static property named GetName for Foo, and store an anonymous function, and then create an anonymous function called GetName for the prototype object of Foo. It then creates a getname function with a function variable expression, and finally declares a function called GetName.
1.foo.getname ()
Foo.getname accesses the static property stored on the Foo function, which is 2.
2.getName ()
The first thing to know is that all declared or declared functions are promoted to the top of the current function, and the function expression does not advance, so the code of the topic is actually the following
functionFoo () {getName=function() {alert (1); }; return This;}varGetName;//Promotion Variable DeclarationfunctionGetName () {alert (5);}//lifting function declarations, overriding VAR declarationsFoo.getname=function() {Alert (2);}; Foo.prototype.getName=function() {Alert (3);}; GetName=function() {alert (4);};//Assignment overrides function GetName declaration againgetName ();//FINAL resultOutput 43.Foo (). GetName ()
Foo (). GetName (); Execute the Foo function first, then call the GetName property function of the return value of the Foo function. The first sentence of the Foo function is GetName = function () {alert (1);}; is a function assignment statement, it does not have a var declaration, so we first look for the getname variable declaration within the scope of the current Foo function, not found. Continue 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 this returned by the Foo function is 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
4.getName ()
Call the GetName function directly, equivalent to executing window.getname (), since this variable has been modified by the third ask Foo function, so the result is the same as the third question, which is 1
5.
New foo.getname (); New Newnew Foo (). GetName ();
About the above three contains the new operator, say, here is the main operator precedence in JS, in fact, the order of execution is as follows
New ( Foo.getname) (); //DOT priority is higher than new, The getname function is executed as a constructor, so it pops up 2 (thenew//parenthesis takes precedence over new, executes the Foo function, and this is returned, and this in the constructor represents the currently instantiated object. So the final Foo function returns the instantiated object.
The GetName function of the instantiated object is then called, because no attributes have been added to the instantiated object in the Foo constructor, and the prototype object (prototype) of the current object is searched for GetName
, found, is 3new ((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
These are the two questions about prototypes, scope closures, variable elevation, and operator precedence
Talk about JS's closure from the face test, prototype