|
Loomulikult oskan ma seda teha vahemuutujat kasutades:
Kuid see on kuidagi väga kohmakas lahendus. Kui ma seda kasutan, siis kirjutan alati juurde kommentaari selgitamaks, mis toimub. Tahaks seda väärtuste vahetamise operatsiooni kuidagi abstraktsemalt esitada. Tahaks kirjutada midagi sellist:
Aga sellist swap funktsiooni pole minu teada võimalik JavaScriptis kirjutada. Või äkki siiski on? Või on mingeid alternatiivseid skeeme kuidas seda operatsiooni sooritada? |
|
Ecmascript 5. versioonis on selline konstruktsioon juba sisse ehitatud, mulle saadaolevatest brauseritest oskab seda süntaksi esialgu ainult Firefox 3.6b1.
Tulemus: a = 10 b = 1 Nüüd on ainult aja küsimus, et millal see teistesse brauseritesse jõuab. |
|
Antile siis vastuseks. Firefox 3.5.4
Seega tundub, et toimib juba praegu FF puhul. :) Kusjuures toimib ka Firefox 3.0 ja Opera 9.
(Nov 10 '09 at 20:47)
Rene Saarsoo ♦♦
|
|
Ma olen küll mitu aastat hiljaks jäänud, kuid panen oma lahenduse ikkagi kirja. Faktitäpsuse huvides mainin esiteks ära, et Anti poolt viidatud destructuring assignment ei ole osa Ecma-262 v5 standardist ning esimene seda toetanud brauser polnud Firefox 3, vaid hoopis Firefox 2 (tugi saabus koos JavaScripti versiooniga 1.7). Tegu on osaga lõpetamata jäänud Ecma-262 v4 osaga ning standardiks saab tõenäoliselt alles kaugel tulevikus v6 (Harmony) osana. Minu one-liner näeks välja aga nii
Tegu pole rangelt võttes päris puhta tehtega, kuna kasutusel on anonüümne massiivivärtus. |
|
Arvatavasti tuleb leppida asjaoluga, et tavaliste muutujate väärtusi niisama lihtsalt ümber vahetada ei saa. Ehk aga õnnestub meil struktureerida oma kood ümber nii, et asjad mille väärtusi vahetatakse pole mitte muutujad vaid mingi objekti koostisosad. Variant 1: MassiividMassiivis kahe elemendi väärtuste vahetamiseks kasutatakse tavaliselt samuti vahemuutuja abi:
Kuid massiivile võime kergesti defineerida elementide vahetamise meetodi:
Ning koodis saab nüüd kirjutada juba üpris arusaadavalt:
Variant 2: VäärtuspaaridSageli on vahetamise operatsiooni tarvis muutujate puhul, mis moodustavad teatud sorti paari. Näiteks programm, mis küsib kasutajalt isiku sünni- ja surma-aasta ning kui surm on enne sündi, siis automaatselt vahetab järjekorra:
Muutujad
Nüüd aga seisab meie ees juba teostatavam ülesanne: objekti väljade väärtuste vahetamine. Selleks saame kergesti kirjutada funktsiooni:
Ning oma koodis seda kasutada:
Need kaks varianti paistavad katvat päris suure hulga juhtudest kus ma tunnen, et mul vahetamise operatsiooni tarvis oleks. |
|
Saan aru, et probleem on selles, et Javascriptis puudub pass-by-reference? Võib-olla saab seda emuleerida mitme tagastatava väärtusega. Ma pole eriline Javascripti kunn, aga PHP-s on olemas selline käsklus nagu list(), mis omistab massiivi väärtused parameetritena antud muutujatele. Ehk siis muutujad vahetab järgmine käsklus:
Iseasi on see, kas see just arusaadavam on kui abimuutuja kasutamine. Abimuutuja on ju klassika, programmeerimise A ja B :). Olen sellest võimalusest PHP puhul teadlik. Kahjuks JavaScriptis
(Nov 05 '09 at 21:11)
Rene Saarsoo ♦♦
|
|
Numbrilisi väärtusi saab teoreetiliselt vahetada ka järgnevalt, kuigi kas see on muidugi otstarbekas.
Mnjah, koodi see kindlasti selgemaks ei tee, pigem vastupidi.
(Nov 06 '09 at 14:38)
Rene Saarsoo ♦♦
Pealegi, mis siis saab, kui ühel ilusal päeval on a ja b mitte arvud vaid arve sisaldavad stringid?
(Aug 03 '11 at 22:53)
dig
|
|
Põhimõtteliselt saab ka nii:
On küll natuke kole, aga kui eesmärk on lihtsalt koodi veidi lühemaks teha, ehk kõlbaks. Nagu Rene tähele pani, ei tööta see variant skoopimisega hästi, ning selle vastu aitaks minu arust ainult veel koledam variant:
Sellel on nüüd omamoodi ajutise muutuja "t" olemasolu probleem, mida saaks ka häkiga lahendada, mis teeks seda asja veel koledamaks, jne... Vastupidi: JavaScripti skoopimine justnimelt EI garanteeri seda. Kui sa kutsud seda swap() funktsiooni välja mõne teise funktsiooni sees kohalike muutujate nimedega, siis üritab swap() vahetada hoopis kahte samanimelist globaalset muutujat.
(Nov 10 '09 at 20:32)
Rene Saarsoo ♦♦
Oh jah, see eval'i skoopimine on tõepoolest puhtalt staatiline, mis tähendab et seda omab mõtet ainult sealkohas välja kutsuda kus muutujaid vahetada peab. Parandasin näidet. Oleks JSil mingi ilus viis dünaamiliselt lokaalsele skoobile ligi pääseda...
(Nov 11 '09 at 10:00)
kt ♦♦
See eval(swap('a','b')) variant on kaval. Muutuja Iseasi on muidugi see, et eval-i kasutamine raskendab JavaScripti minimiseerijate tööd - selle funktsiooni muutujate nimesid, milles eval-i kasutatakse, ei saa lühendada.
(Nov 11 '09 at 13:02)
Rene Saarsoo ♦♦
|
