已知以下一段代碼,請回答問題。
function Foo (){
getName = function (){
alert(1);
};
return this;
}
Foo.getName = function (){
alert(2);
};
Foo.prototype.getName = function () {
alert(3);
};
var getName = function (){
alert(4);
};
function getName (){
alert(5);
};
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
請回答:各部分的輸出是什麼?
2
4
1
1
2
3
3
解答思路:
- 最開始的變量對象:
VO (globalContext) = {
Foo:{
<reference to function>,
return this
}
getName: <reference to function>{alert(5)}
}
- 執行 Foo.getName = function (){alert(2);}
VO (globalContext) = {
Foo:{
<reference to function>,
getName: <reference to function>{alert(2)},
return this
}
getName: <reference to function>{alert(5)}
- 執行 Foo.prototype.getName = function () {alert(3);};
VO (globalContext) = {
Foo:{
<reference to function>,
getName: <reference to function>{alert(2)},
prototype: {
getName: <reference to function>{alert(3)}
},
return this
}
getName: <reference to function>{alert(5)}
}
- 執行 var getName = function (){alert(4);};
VO (globalContext) = {
Foo:{
<reference to function>,
getName: <reference to function>{alert(2)},
prototype: {
getName: <reference to function>{alert(3)}
},
return this
}
getName: <reference to function>{alert(4)}
}
-
執行 Foo.getName():
從 VO 中看到 :alert(2) -
執行 getName():
從 VO 中看到 :alert(4) -
執行 Foo().getName():
Foo() 調用之後返回 this(指向window),所以 Foo().getName() 等價於 window.getName()
但是Foo() 調用改變了 VO
VO (globalContext) = {
Foo:{
<reference to function>,
getName: <reference to function>{alert(2)},
prototype: {
getName: <reference to function>{alert(3)}
},
return this
}
getName: <reference to function>{alert(1)}
}
所以 Foo().getName() 最後返回 alert(1)
-
執行 new Foo.getName():
因爲 new 操作符的優先級低於屬性訪問符,所以先執行 Foo.getName(),返回 alert(2) -
執行 new Foo().getName():
Foo() 和 new Foo() 相比, new Foo() 優先級更高,所以先執行 new Foo(),new 出來的對象繼承了 Foo.prototype ,因此 alert(3) -
執行 new new Foo().getName():
先執行 new Foo(),所以alert(3)