3 回答

TA貢獻1786條經驗 獲得超13個贊
1)您可以檢查this.constructor:
function x(y)
{
if (this.constructor == x)
alert('called with new');
else
alert('called as function');
}
2)是的,在new上下文中使用時,返回值只是被丟棄

TA貢獻1898條經驗 獲得超8個贊
注意:現在可以在ES2015及更高版本中使用。請參閱Daniel Weiner的答案。
我認為[ES2015之前]您想要的東西是不可能的。函數內根本沒有足夠的信息來進行可靠的推斷。
查看ECMAScript 3rd Edition規范,new x()調用時所采取的步驟實質上是:
創建一個新對象
將其內部的[[Prototype]]屬性分配給的prototype屬性 x
x正常調用,將新對象傳遞給this
如果調用x返回了對象,則返回它,否則返回新對象
對于執行代碼而言,有關如何調用該函數的任何有用信息都沒有,因此唯一可以在內部進行測試的x就是this值,這就是這里所有答案的作用。如您所見,作為構造函數x調用時,*的新實例與作為函數調用時所傳遞x的既有實例沒有區別,除非您為構造時創建的每個新對象分配一個屬性:xthisxx
function x(y) {
var isConstructor = false;
if (this instanceof x // <- You could use arguments.callee instead of x here,
// except in in EcmaScript 5 strict mode.
&& !this.__previouslyConstructedByX) {
isConstructor = true;
this.__previouslyConstructedByX = true;
}
alert(isConstructor);
}
顯然,這并不理想,因為您現在對每個x由此構造的對象都擁有一個額外的無用屬性,但該屬性可能會被覆蓋,但我認為這是您可以做的最好的事情。
(*) “ instance of”是一個不準確的術語,但足夠接近,并且比“通過調用x構造函數創建的對象”更為簡潔
添加回答
舉報