2016-02-29 11 views
5

Próbuję zrozumieć zachowanie JavaScript (lub przynajmniej V8) dotyczące funkcji konstruktora.Dlaczego funkcje konstruktora zwracają obiekty, ale nie prymitywy w JavaScript?

Wiem, funkcje konstruktora JavaScript nigdy nie powinny zwracać niczego (czyli: undefined).

jednak rozważyć tę JavaScript:

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

Teraz, jeśli to zrobić:

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

a nawet:

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

Więc dlaczego funkcję konstruktora w zamian JavaScript obiekt, ale nie prymitywny, jeśli napiszesz ten rodzaj kodu?


To zachowanie jest również wymienione w this SO answer, ale nie wyjaśniono. Przejrzałem także część specyfikacji ECMAScript pod kątem The new Operator i jej Construct, ale nie było to oświecenie.

Wszelkie wskazówki lub wiedza (w prostym języku angielskim, proszę)?

+2

Cóż, po pierwsze, nie jest "źle i brzydko", ponieważ nie robi tego, co myślisz, że jest. I dlaczego zwróciłby prymityw, skoro nie jest to prymitywny obiekt? –

+3

W skrócie: jeśli zwrócisz prymitywę z konstruktora, zostanie ona zignorowana. Jeśli zwrócisz obiekt, zostanie on użyty jako wynikowy obiekt. Czy to odpowiada na pytanie? A może szukasz przesłanki tego zachowania? – deceze

+5

Zachowuje się w ten sposób "ponieważ specyfikacja mówi tak". Myślę jednak, że wyjaśnienie "dlaczego", którego szukasz, może być oparte na opiniach - musisz uzyskać odpowiedź, która pokazuje rozumowanie zespołu projektującego język, wszystko inne jest po prostu opinią kogoś innego - na przykład tutaj: moje: nazwałeś 'new', więc spodziewasz się obiektu, być może zespół projektujący język czuł, że powinieneś zawsze otrzymać obiekt, nawet jeśli funkcja zwraca prymityw, ale nie mam nic solidnego do poparcia tego rozumowania. –

Odpowiedz

4

To dlatego, że z definicji, celem konstruktorów produkuje przedmioty, a nie prymitywów:

4.3.4 constructor

funkcja obiektu, który tworzy i Zainicjowanie obiektów

Dlatego [[Construct]] wewnętrzny metoda (wywołana przez new operator), sprawdza typ wartości zwracanej przez [[Call]]:

13.2.2 [[Construct]]

  1. Niech wynik być wynikiem wywołanie [[połączeń]] właściwość wewnętrznej z F, zapewniając obj jako to wartość i dostarczenie listy argumentów przekazanych do [[Construct]] jako args.
  2. Jeśli Type (wynik) jest Object, następnie zwróć wynik.
  3. Powrót obj.

W rzeczywistości jest to invariant:

[[Konstrukt]]()

  • typ wartości powrotnej musi obiektów.
+0

Link do Twojego komentarza. Nie zauważyłem tego. Dzięki. Moim zdaniem nie ma to większego sensu - ale to nie jest miejsce na opinie :). – BairDev

Powiązane problemy