2016-02-29 44 views
5

我想了解JavaScript的(或至少是V8的)有關構造函數的行爲。爲什麼構造函數返回對象,但不是JavaScript中的基元?

我知道,JavaScript構造函數不應該返回任何東西(如:undefined)。

但考慮這個JavaScript:

function Thing() { 
    return ''; 
} 
var t = new Thing(); 
console.log(t, typeof t); // => Thing {} "object" 

現在,如果你這樣做:

function Thing() { 
    return { hi: '' }; 
} 
var t = new Thing(); 
console.log(t, typeof t); // => Object {hi: ""} "object" 

甚至:

function Thing() { 
    this.a = 'a'; 
    return { hi: '' }; 
} 
var t = new Thing(); 
console.log(t, typeof t); // => Object {hi: ""} "object" 

那麼,爲什麼在JavaScript中返回一個構造函數一個對象,但不是一個原始的,如果你寫這種類型的代碼?


此行爲在this SO answer中也有提及,但未說明。我也瀏覽了ECMAScript規範的The new Operator部分,並對其Construct進行了縮減,但這並不具有啓發性。

任何提示或知識(請用簡單的英語)?

+2

對於其中一個,它不是「錯誤和醜陋」,因爲它沒有按照你的想法去做。當它不是一個原始對象時爲什麼會返回一個基元? –

+3

簡而言之:如果從構造函數返回一個基元,它將被忽略。如果您返回一個對象,則將其用作結果對象。這是否回答了這個問題?或者你在尋找這種行爲的基本原理嗎? – deceze

+5

它的行爲方式是「因爲規格說明是這樣」。然而,我認爲你所尋找的「爲什麼」的解釋可能真的是基於意見的 - 你需要得到一個顯示語言設計團隊推理的答案,其他的只是某人的意見 - 例如,這裏是我的:你已經調用'new',所以你期待一個對象,也許語言設計團隊認爲你應該總是得到一個對象,即使該函數返回一個原語,但我沒有什麼可靠的支持該推理。 –

回答

4

這是因爲按照定義,構造的目的是生產的對象,而不是原語:

4.3.4 constructor

函數對象創建和初始化對象

因此,[[Construct]]內部方法(通過new operator調用)檢查由[[Call]]返回的值的類型:

13.2.2 [[Construct]]

  • 結果是調用的結果[[調用]的˚F內部屬性,提供OBJ值並且提供 傳遞到[[Construct]]的參數列表,作爲參數
  • 如果Type結果)是Object,則返回結果
  • 返回obj
  • 事實上,這是一種invariant

    [[構建]]()

    • 返回值的類型必須是對象。
    +0

    像你評論中的鏈接。我沒有發現。謝謝。我認爲這沒什麼意義 - 但這不是意見的地方:)。 – BairDev

    相關問題