Recently, I encountered a classic Foo and getName interview question. After reading several answers, I felt a little difficult to understand, so I realized it according to my own ideas and took notes

The title as follows

function Foo() {
  getName = function () {
    console.log(1);
  };
  return this;
}
Foo.getName = function () {
  console.log(2);
};
Foo.prototype.getName = function () {
  console.log(3);
};
var getName = function () {
  console.log(4);
};

function getName() {
  console.log(5);
}

Foo.getName();
getName();
Foo().getName(); 
getName();
new Foo.getName(); 
new Foo().getName();
new new Foo().getName();
Copy the code

When we’re faced with a problem like this, we have to be aware of it and let’s first draw a picture to clarify our thinking

First of all, JS doesn’t execute our code immediately. Instead, the engine transforms the JS code we write into executable code through lexical analysis, and then executes the code after execution

function getName(){
   console.log(5);
}
var getName;
 
getName = function(){
  console.log(4);   
}
Copy the code

So the function declaration getName is overwritten and now the global getName returns 4

The next line of code executes foo.getName (), which normally returns 2

The second getName() variable promotion modified the global and now returns 4

Third Foo().getName() according to the figure above, when we call Foo(), we return to match this. This will change the global window and then call getName(), which will change the global getName to return 1

The fourth getName() we modify the global getName to continue returning 1

The fifth new foo.getName () is where we need to know the priority of js executionSince member access to ‘.’ takes precedence over new, Foo. GetName () is executed first, and new is executed after = “new (foo.getName ()) (), new returns an instance of foo.getName (), and returns 2

The sixth new Foo().getName(), the main hesitation is to execute Foo() first, because new takes arguments, GetName () = (new Foo()).getName() = getName() on Foo(

And finally new new Foo().getName()

New with parameters will be executed first.

New (new Foo().getName())()

New ((new Foo()).getName())()

First evaluates new Foo(), then gets getName(), then evaluates new () on the fetch, then calls;

New ((new Foo()).getName())() = new(foo.prototype.getName)(

So the final answer is 2, 4, 1, 1, 2, 3, 3