- 求下列函数输出结果
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()
- 首先由变量提升阶段
// Global
Foo = 0xffffff00
getName = () -> 5  // () -> 5 代表函数引用类型,输出5
-  然后到执行阶段,从上到下一行行执行 
-  Foo.getName = function(){}
// 0xffffff00
getName: () -> 2
- Foo.prototype.getName = function(){}
// 0xffffff00
getName: () -> 2
prototype: 0xffffff01
// 0xffffff01
getName: () -> 3
- getName = function(){}
// Global
Foo = 0xffffff00
getName = () -> 4
-  Foo.getName(), 顺着内存地址找输出2
-  getName(): 输出4
-  Foo().getName(),先执行Foo,在执行getName-  执行 Foo
-  // ctx: Foo getName(全局) = () -> 1 // return this // 由于Foo函数是在全局环境下执行,因此this执行window return window // 执行完即销毁
-  执行完毕后,Global中的getName改变 
-  // Global Foo = 0xffffff00 getName = () -> 1
-  此时,相等于执行 window.getName(), 直接输出1
 
-  
-  getName(),输出1
-  new Foo.getName(): 根据优先级new ...是18, 而.是19,因此先执行后面的- Foo.getName(): 输出2
- 再执行new
 
-  new Foo().getName():new Foo()的优先级是19, 和.是一样的,因此从左往右执行- new Foo(): 创建一个Foo实例f,然后执行- f.getName方法.
- 实际上就是执行Foo.prototype.getName,会输出3
 
-  new new Foo().getName(): 这个可以看作:new ((new Foo()).getName()),还是输出3
-  综上所述输出: 2 4 1 1 2 3 3