- 求下列函数输出结果
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