Autor Zpráva
hypot
Profil
Několik jednoduchých proměnných se stejnou výchozí (počáteční) hodnotou lze vytvořit například takto:
var promenna1 = promenna2 = 0
Když pak změním hodnotu druhé proměnné (promenna2 += 5), bude výsledek ten, že v proměnné promenna2 bude hodnota 5 a v proměnné promenna1 hodnota 0.

Na základě výše zmíněného by se dalo dovodit, že stejným způsobem se dá vytvořit i několik prázdných polí (což jsou rovněž proměnné):
var pole1 = pole2 = []
Jenže když následně vložím nějakou hodnotu do druhého pole (pole2.push(5)), bude výsledek ten, že v poli pole2 bude hodnota 5, ale v poli pole1 bude rovněž hodnota 5.

Jistě bych se mohl spokojit s tím, že víc prázdných polí nelze vytvořit uvedeným způsobem, a v praxi by to stačilo. Mě nicméně zajímá důvod tohoto rozdílu. Proč se pole vytvořená stejným způsobem jako jednoduché proměnné chovají jinak?
Mlocik97
Profil
protoze u plo sa predava reference na zaciatok pola resp. na prvy prvok pola, nikoliv hodnota vsech prvku pola. Samozrejme su aj moznosti ako pole naklonovat.
Radek9
Profil
hypot:
Několik jednoduchých proměnných se stejnou výchozí (počáteční) hodnotou lze vytvořit například takto:
Už tady je to špatně. Proměnná se definuje příkazy var, let nebo const. Pokud to definuješ tak, jak jsi to napsal, tak definuješ pouze proměnnou promenna1. Proměnná promenna2 je v tu chvíli mimo příkaz a je definována jako globální proměnná, což ve většině případů nechceš.

Příkaz var promenna1 = 0; se dá ve skutečnosti rozepsat takto:

var promenna1;
promenna1 = 0;

V tvém případě se tedy provede následující:
var promenna1;
promenna2 = 0; // Vzhledem k tomu, že nebyla proměnná definovaná pomocí jednoho z uvedených příkazů, je globální
promenna1 = promenna2;

Správně je to tedy takto:
var promenna1, promenna2;
promenna1 = promenna2 = 0;

nebo:
var promenna1 = 0, promenna2 = 0;

Na základě výše zmíněného by se dalo dovodit, že stejným způsobem se dá vytvořit i několik prázdných polí (což jsou rovněž proměnné):
Tady je podstatné si uvděomit, že je zásadní rozdíl mezi primitivními hodnotami (čísla, řetězce, booly) a objekty. Primitivní hodnoty se v JS předávají napřímo. Pokud tedy uložíš do dvou proměnných stejnou primitivní hodnotu, tak se nakopíruje. Pole je ale objekt. A objekty jsou v JS předávány pomocí reference. Pokud to uděláš tak, jak jsi to napsal (na chybu s nevyžádanou globální proměnnou jsem již upozornil), tak obě proměnné odkazují (tedy obsahují stejnou referenci) na totožný objekt. Kopíruje se tedy jen reference (odkaz), ale nikoli již příslušný objekt. Správně je tedy toto řešení:
var promenna1 = [], promenna2 = []; // Proměnné obsahují reference na 2 různé objekty
Kcko
Profil
hypot:
Tohle chování má PHP, ne JS.
TomášK.
Profil *
Kcko:
Javascript také.

var a = b = [];
a.push(42);
console.log(b); //Array [ 42 ]
_es
Profil
Radek9:
Proměnná promenna2 je v tu chvíli mimo příkaz a je definována jako globální proměnná, což ve většině případů nechceš.
To nie je celkom správny popis, promenna2 nie je v tom prípade definovaná ako globálna premenná, ale len ako vlastnosť "promenna2" globálneho objektu, čo nie je to isté. Napríklad operátor delete dokáže odstrániť "premennú" promenna2 no nie premennú promenna1. Ak by bol použitý "striktný mód", tak hypotov príkaz vyvolá chybu.
Keeehi
Profil
TomášK.:
Kcko ovšem částí "Tohle chování" měl samozřejmě na mysli chování hypotem předpokládané, že přiřazením pole vzniká v PHP jeho kopie. Příště si prosím nejdříve pořádně přečti co pisatel píše a hlavně popřemýšlej, co tím myslí.
TomášK.
Profil *
Keeehi:
Dík, zdálo se mi, že něco nesedí – leželo to tu poměrně dlouho a nikdo se neozval. Nenapadlo mě, že se php dělá kopie, předpokládal jsem, že se chová stejně jako javascript, python nebo ruby a předává jen odkaz na pole.
Radek9
Profil
_es:
Máš samozřejmě pravdu, hodně jsem pro účely téhle ukázky zjednodušoval. Použití strict modu většinu podobných problémů řeší.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0