2013-03-27 22 views
12

Ponieważ ciągi znaków w języku JavaScript są typami podstawowymi, czy przekazanie ciągu znaków do funkcji tworzy jego lokalną kopię? Zastanawiam się nad tym, ponieważ nie można modyfikować ciągów po ich utworzeniu, więc wydaje się nielogiczne, że maszyny wirtualne JavaScript nie przekazałyby wewnętrznego adresu łańcucha tylko do tej funkcji.Czy przekazywanie ciągu znaków do funkcji kopiuje ją według wartości lub przekazuje przez odniesienie?

Jeśli ktoś mi powie, że nie powinienem się o to martwić (często zdarza się to podczas rozmowy z twórcami stron), pracuję nad grami HTML5, a zbieranie śmieci jest poważnym problemem, więc naprawdę potrzebuję wiedzieć.

+4

Może głupie pytanie, ale dlaczego po prostu tego nie spróbujesz? – Uby

+2

Każdy typ pierwotny jest przekazywany według wartości. Zobacz http://snook.ca/archives/javascript/javascript_pass –

+0

@silentboy: Wartości ciągów mogą być traktowane jak prymitywy, ale ja * gwarantuję * tobie, ciąg nie jest przekazywany przez wartość. –

Odpowiedz

10

Ciąg zostanie przekazany jako odniesienie.

Ciąg znaków nie jest zmienny, więc przy każdej próbie zmiany otrzymujesz nowy ciąg znaków (np. Robiąc value+="more").

zobacz także: What does immutable mean?

@ T.J. Crowder: by value vs by ref - jeśli patrzysz na definicję języka, masz rację. Jednak nie sądzę, że istnieje implementacja, która faktycznie tworzy kopię ciągu, ponieważ byłaby niesamowicie powolna. Ponieważ ciągi są niezmiennymi elementami pierwotnymi, nie ma potrzeby ich kopiowania, ponieważ nie można ich zmienić.

+2

* "Łańcuch zostanie przekazany jako odniesienie". * Podajesz to jako fakt. Czy masz na to dowód? Wierzę, że to prawda (lub dokładniej, uważam, że odniesienie do ciągu znaków jest przekazywane wartością, ** nic ** w JavaScript jest "przekazywaniem przez odniesienie"), ale bez możliwości cytowania czegoś, zawaham się go podać jako łysy fakt. –

+0

@ Chris: Nie mówię, że kopiowana zawartość ciągu jest kopiowana.Jestem pewien, że nie są (jak powiedziałem w mojej odpowiedzi), że odniesienie do tych treści jest przekazywane (przez wartość) do funkcji. –

+0

Wiem, że ciągi są niezmienne, powiedziałem, że w pytaniu, właśnie dlatego poprosiłem o to w pierwszej kolejności. Prawdopodobnie przyjmuję tę odpowiedź jutro, chyba że ktoś da referencje. Odpowiedź jest oparta na zdrowym rozsądku, choć myślę, że trudno jest prosić o więcej, jeśli chodzi o te rzeczy. – dreta

5

Uważam, że specyfikacja milczy w tej kwestii. Jednak byłoby to naprawdę idiotyczne wdrożenie, które przekazywałoby rzeczywistą zawartość ciągu, a nie przekazywanie odniesienia do tej zawartości w pamięci, nawet jeśli łańcuchy są teoretycznie "prymitywami". Podejrzewam, że większość implementacji traktuje "prymitywne" struny tak samo, jak traktują odwołania do obiektów (w tym względzie, oczywiście nie w niektórych innych, takich jak ===), ale po prostu nie z pułapkami Object.

+0

Niezły punkt na '==='. – Taurus

+0

Jeśli odniesienie do czegoś zostanie przekazane, to czy nie byłoby bardziej uzasadnione dla 'b' w poniższym przykładzie, aby mieć również właściwość' bar'? 'var a =" foo " var b = a; a ["bar"] = "baz"; konsola.log (b ["bar"]); "Teraz jestem przekonany, że coś jest nie tak z boksem, które wywołuje we mnie zamieszanie, co to jest? – Taurus

+0

@Taurus: To jest myląca część JavaScript, ale jest objęta specyfikacją. :-) Pamiętaj, że JavaScript ma zarówno prymitywy typu * *, jak i osobno ciąg * obiekty *. 'a' [zawiera/ma odniesienie do] * pierwotnego * ciągu' "foo" '. Instrukcja "a [" bar "] =" baz "' pobiera pierwotny ciąg z "a", ale ponieważ używa go jako obiektu, nowy tymczasowy obiekt napisowy jest tworzony i używany dla tej części wyrażenia. Ten tymczasowy obiekt typu string otrzymuje właściwość 'bar', ale ponieważ nic nie zapisuje ... * (ciąg dalszy) * –

Powiązane problemy