- 求下列函數輸出結果
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