2010-10-11 12 views
27

Nie żartuję sobie z żartu, naprawdę pytam.W jaki sposób łańcuch JavaScript nie jest obiektem?

Douglas Crockford is fond of saying że w języku prototypowym obiektowo zorientowanym javascript nie ma potrzeby, aby new.

Wyjaśnia, że ​​new po prostu dodaje do osób pochodzących z (czyli „klasycznych”) obiektowych języków programowania opartych na klasach pewien poziom komfortu:

JavaScript, We Hardly new Ya

JavaScript jest prototypowy język, ale ma operatora new, który stara się, aby wyglądał jak klasyczny język. To często wprowadza w błąd programistów, prowadząc do pewnych problematycznych wzorców programowania.

Nigdy nie musisz używać new Object() w JavaScript. Zamiast tego użyj obiektu literalnego {}.

Dobra, w porządku:

  • new złe
  • {} dobry

Ale potem komentator Vítor De Araújo pointed out that the two are not the same. Podaje przykład pokazujący, że string nie jest jak object:

obiektu String i wartość ciągu nie jest to samo:

js> p = "Foo" 
Foo 
js> p.weight = 42 
42 
js> p.weight // Returns undefined 

js> q = new String("Foo") 
Foo 
js> q.weight = 42 
42 
js> q.weight 
42 

Wartość ciągu nie można mieć nowe właściwości. To samo dotyczy innych typów.

Co się tutaj dzieje, że string nie jest object? Czy mylić javascript z innymi językami, gdzie wszystko jest przedmiotem?

+0

... a ja nie zupełnie zgadza się z Crockforda: to nie jest konieczne jest użycie "nowego obiektu" (ani "nowa tablica", zamiast tego użyj '[]', ale jeśli chcesz zdefiniować nowe wystąpienie (pre) zdefiniowanej klasy, powinieneś użyć operatora 'new', jak w 'new Date()' lub 'new SchrodingersCat()'. –

+0

@Marcel Korpel: * "należy użyć" * lub ** musi ** * użyć *? Czy istnieje inny sposób skonstruowania nowego obiektu z prototypu obiektu "Date"? –

+0

Dobre pytanie, w przypadku "Date": ** must **. Jeśli wywołasz "Date" jako funkcję bare, zwraca ona bieżącą datę i czas jako ciąg znaków. Zobacz także [Używanie konstruktora bez operatora 'new'] (http://stackoverflow.com/questions/1928342/using-constructor-without-operator-new) i [Czy nowy operator JavaScript robi cokolwiek, ale utrudnia życie?] (Http : //stackoverflow.com/questions/1744426/does-javascripts-new-operator-do-anything-but-make-life-difficult) –

Odpowiedz

57

"Wszystko jest przedmiotem" ... to jedno z wielkich nieporozumień, które istnieją w całym języku.

Niewszystko jest obiektem, istnieją co nazywamy wartości prymitywne, które są ciąg, numer, Boolean, null, a niezdefiniowane.

To prawda, ciąg znaków jest wartością domyślną , ale można uzyskać dostęp do wszystkich metod odziedziczonych po String.prototype, tak jakby był obiektem.

Właściwość accessor operators (notatka i nawias klamrowy), tymczasowo przekonwertuj wartość ciągu na obiekt typu String, aby uzyskać dostęp do tych metod, np.:

"ab".charAt(1); // "b" 

Co się dzieje za kulisami jest coś takiego:

new String("ab").charAt(1); // "b", temporal conversion ToObject 

Podobnie jak w przypadku innych wartości pierwotnych, takich jak Boolean i Number istnieją obiektów owijarki, które są po prostu obiektów które zawierają prymitywną wartość, jak w twoim przykładzie:

var strObj = new String(""); 
strObj.prop = "foo"; 

typeof strObj; // "object" 
typeof strObj.prop; // "string" 

Z primitem ive:

var strValue = ""; 
strValue.prop = "foo"; 

typeof strValue; // "string" 
typeof strValue.prop; // "undefined" 

A dzieje się tak dlatego kolejny accessor nieruchomość w drugim wierszu powyżej, tworzy nowy obiekt czasowej, jak:

var strValue = ""; 
new String(strValue).prop = "foo"; // a new object which is discarded 
//... 
+1

Wolę nie używać wielkich liter z prymitywami, takich jak 'boolean' i' liczba', aby uniknąć zamieszanie z obiektami owijającymi 'Boolean' i' Number' (ale specyfikacja ECMAScript tego nie robi). Również 'NaN' jest wartością pierwotną. –

+0

Marcel, tak, owijacze obiektów mogą powodować zamieszanie, np. 'if (new Boolean (false)) {alert (': D');}'. Tak, 'NaN', dodatnie i ujemne' Infinity' są wartościami typu [Number type] (http://ecma262-5.com/ELS5_HTML.htm#Section_8.5). – CMS

+1

Ach, tak, 'Nieskończoność', już pomyślałem, że zapomniałem o jakiejś innej wartości. Jak można zapomnieć o 'Infinity'? –

Powiązane problemy