以下代码段的执行结果求解释。

function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
Foo.prototype.a = function() {
    console.log(3)
}
Foo.a = function() {
    console.log(4)
}
Foo.a();
let obj = new Foo();
obj.a();
Foo.a();

这个代码执行结果是 4 2 1
obj.a()为什么输出2???

自问自答一下
Foo.a();
这个输出4的原因是因为function Foo() 定义后并没有执行,等到调用才会去执行,所以内部并未执行
所以Foo.a()会先从自身找属性,找到了console.log(4)这个方法

let obj = new Foo();
这里讲对象进行了实例化,Foo函数执行了一次,且内部的this指向实例本身

obj.a();
此时obj.a()同样是从obj这个对象属性上找,console.log(2)

Foo.a();
从对象Foo属性上找a方法,此时找到了console.log(1)

为什么3这个没有执行呢,是因为对象静态属性上找到了该函数,要是找不到,那么就会到原型链上寻找,一直找到顶层Object()
要想执行3,那么可以先把对象上的实例属性去删除,那么就会执行原型上的方法,输出3

this.a这个等价于面向对象语言中(如java/c#)的构造函数,new Foo();即调用构造无参的构造函数,所以obj.a()为2