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();
20 行的会在变量 / 函数提升,被 16 行重新赋值,所以 window.getName() 是 console.log(4);
Foo.getName(); 对应第 8 行,输出 2
getName(); 对应 window.getName(); ,输出 4
Foo().getName();
- 首先第 2 行执行,Foo() 的词法环境是 window, getName 是 window 的 getName。所以这里又重新赋值 window.getName 为 console.log(1);
- Foo() 执行后返回 this,这个 this 是指向 window,对应
window.getName();,输出 1
getName(); 对应 window.getName(); ,在第 2 行执行时已经修改,输出 1

成员访问比 new 无参数列表的优先级高,但 new 有参数列表是与成员访问一样的,
即 new 是对应到出现 () 为止,把那部分作构造函数
new Foo.getName(); 是 new 第 8 行的构造函数,输出 2
new Foo().getName(); 是 new 第 1 行的构造函数,
- 返回 this 是 Foo 的实例
- 其实例没有 getName() 方法,所以会向其原型上找
- 找到第 12 行,所以输出 3
new new Foo().getName();
new Foo()是 new 第 1 行的构造函数, 返回 this 是 Foo 的实例记作 foonew foo.getName(), 成员访问比 new 无参数列表的优先级高,foo 没有 getName 又从其原型找foo.getName()就是第 12 行的原型,然后 new Foo.prototype.getName(),输出 3
2411233
