參考連接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
經過查上表能夠得知點(.)的優先級高於new操做,遂至關因而:
new (Foo.getName)();
因此實際上將getName函數做爲了構造函數來執行,遂彈出2。
第六問:new Foo().getName(); //3
首先看運算符優先級: 括號高於new,實際執行爲 (new Foo()).getName()
遂先執行Foo函數,而Foo此時做爲構造函數卻有返回值,因此這裏須要說明下js中的構造函數返回值問題。
構造函數的返回值:
在傳統語言中,構造函數不該該有返回值,實際執行的返回值就是此構造函數的實例化對象。
而在js中構造函數能夠有返回值也能夠沒有。
一、沒有返回值則按照其餘語言同樣返回實例化對象。
二、如有返回值則檢查其返回值是否爲引用類型。若是是非引用類型,如基本類型(string,number,boolean,null,undefined)則與無返回值相同,實際返回其實例化對象。
三、若返回值是引用類型,則實際返回值爲這個引用類型。
原題中,返回的是this,而this在構造函數中原本就表明當前實例化對象,遂最終Foo函數返回實例化對象。
以後調用實例化對象的getName函數,由於在Foo構造函數中沒有爲實例化對象添加任何屬性,遂到當前對象的原型對象(prototype)中尋找getName,找到了。
遂最終輸出3。
第七問:new new Foo().getName(); //3
一樣是運算符優先級問題。最終實際執行爲:
new ((new Foo()).getName)();
先初始化Foo的實例化對象,而後將其原型上的getName函數做爲構造函數再次new。
遂最終結果爲3
===2016年03月23日更新===
這裏引用 @於明昊 的評論,更詳細的解釋了第7問:
這裏確實是(new Foo()).getName(),可是跟括號優先級高於成員訪問不要緊,實際上這裏成員訪問的優先級是最高的,所以先執行了 .getName,可是在進行左側取值的時候, new Foo() 能夠理解爲兩種運算:new 帶參數(即 new Foo())和函數調用(即 先 Foo() 取值以後再 new),而 new 帶參數的優先級是高於函數調用的,所以先執行了 new Foo(),或得 Foo 類的實例對象,再進行了成員訪問 .getName。
關於第七問的解釋有點暈,歡迎你們指點迷津