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