Objektum többszörös értékadás

Objektum többszörös értékadás
2020-05-23T17:55:34+02:00
2020-05-24T19:04:37+02:00
2022-10-15T21:25:20+02:00
dalee
Sziasztok,

Az alábbi kód nem azt csinálja, amit gondolnék:

var msg1 = {}; var msg2 = {}; var a = []; var b = {}; b.ts = Date.now(); b.temp = 12.5; a.push(b); msg1.payload = b; b.ts = Date.now(); b.temp = 32.5; a.push(b); msg2.payload = b; return [msg1,msg2];
Azt vártam volna, hogy az msg1.payload.temp  12.5 lesz, az msg2.payload.temp pedig 32.5.
A várt eredmény helyett az msg1 és az msg2 temp 32.5 lesz, illetve mindkét ts a második időbélyeget kapja.
Egy objektum elemnének nem lehet menet közben más értéket adni, az utolsó értékadást veszi fel már a futásidő elején és ha így van hogyan tudok értéket módosítani?
Mutasd a teljes hozzászólást!
Valószínűleg az zavar össze téged, hogy Javascriptben az objektumok referenciákon keresztül érhetőek csak el. Amikor egy objektumot "beleraksz" egy másikba (jelen esetben tömbbe), akkor nem egy másolat kerül be, hanem hivatkozás az eredeti objektumra.

A kódodban létrehozol egy objektumot, ráállítod a b változót, belerakod a referenciáját egy tömbbe, aztán átírod az objektum mezőit és még egy referenciát raksz a tömbbe. Nem csoda, hogy ugyanazt az értéket látod kétszer, hiszen ugyanaz az objektum!

Ha másik objektumra van szükséged, akkor hozz létre egy újat:

var msg1 = {}; var msg2 = {}; var a = []; var b = {}; b.ts = Date.now(); b.temp = 12.5; a.push(b); msg1.payload = b; b = {}; // új objektumot hozunk létre és ráállítjuk a "b" változót b.ts = Date.now(); b.temp = 32.5; a.push(b); msg2.payload = b; return [msg1,msg2];
Mutasd a teljes hozzászólást!

  • Szerk: Csaboka2 gyorsabb volt
    Mutasd a teljes hozzászólást!
  • Szia,

    Köszönöm a segítséget.
    Mutasd a teljes hozzászólást!
  • Ami még a témával kapcsolatban nem sikerült, hogy tudom a tömböt, melyben a fenti példában két objektum van visszaadni, azaz:

    return a;
    helyett mit kellene használni.

    (Igazából a node-red-ben az egyik node adná át a másik node-nak az objektumok tömbjét)
    Mutasd a teljes hozzászólást!
  • Nem értem a kérdést. Mi baj van a "return a"-val? Az pont visszaadja azt a tömböt, amiben a két objektum van.
    Mutasd a teljes hozzászólást!
  • Próbálkoztam, az alábbi módon nem működik:

    1. node: 

    var no = []; msg = {}; msg.no = 1; msg.no2 = 2; no.push(msg); msg = {}; msg.no = 3; msg.no2 = 4; no.push(msg); msg = {}; msg = no; return msg;
    Így a visszatérő érték egy objektum, melynek két eleme van:  n0:1 és no2:2;

    Ha a 'msg =no;' sort kicserélem "msg.payload = no;"-ra akkor a payload-ba már két elemű array-ként látszik, azaz a msg egy objektum melynek payload eleme 2 elemű tömb, melynek mindkét eleme objektum [0] n0:1 és no2:2   ,  míg [1]: n0:3 és no2:4

    Azaz a msg nem lett két elemű tömb, , viszont az msg.payload esetében a payload  már igen. 
    Lehet, hogy ez a node-red belső működéséből következik, mivel a node -ok között az msg a kapocs?
    Mivel az msg-t a node kapja, ezért nincs a program elején 'var'-al deklarávla a msg változó.
    Mutasd a teljes hozzászólást!
  • Gondold át még egyszer. A változók rámutatnak objektumokra, nem pedig tartalmazzák őket. Amikor leírsz egy ilyet:

    msg = no;
    akkor azt akarod, hogy az "msg" változó innentől ugyanarra az objektumra mutasson, mint a "no" változó. Ez semmilyen formában nem befolyásolja azt az objektumot, amire az "msg" változó eddig mutatott.

    Ha viszont ezt írod:

    msg.payload = no;
    akkor azt kéred, hogy vegye a futtatómotor azt az objektumot, amire az "msg" változó mutat, hozza létre rajta a "payload" tulajdonságot (ha még nem létezik), és állítsa az értékét arra az objektumra, amire most a "no" mutat. Tehát nem a változót állítod másik objektumra, hanem az objektumot módosítod.

    A node-redhez nem értek, és mivel kb. fél perc kattintgatással az oldalukon nem jutottam el komoly példáig, nem tudom hogy kezeli az üzeneteket. Elvileg lehetséges, hogy azt az objektumot figyeli, amit átadott a kódodnak, nem pedig a visszatérési értéket, de ha így van, akkor nem értem miért várja el egyáltalán, hogy bármivel visszatérj.
    Mutasd a teljes hozzászólást!
  • Azt első részben leírtakat értem (legalább is úgy gondolom), az msg is a no objektumra fog mutatni.

    Bár azt már nem értem, ha ezt a mutatót a return-ba visszaadom akkor miért csak az első elemet éri el a következő node (hívó függvény), vagy a mutató csak az első elemre mutat a visszatérő értéket kezelő eljárás nem tudja hány elemű a tömb? Esetleg az objektum megsemmisül, mivel azt a példa eljárásban hoztuk létre és a return után megsemmisül az eredeti objektum?

    Az msg.payload esetében értelmezésem szeint ugyanazt írtad, illetve én is így értlemezem, hogy bér létrejön a payload tulajdonság, de az ugyanúgy a no objektum címét veszi fel vagy létrejön egy objektum amit visszaad a return- on keresztül.

    Még pont azt akartam kérdezni, hogy mi semmisíti meg az objektumot.

    Nem lehet, mivel nem a fenti példa eljárásban kerül deklarálásra az msg objektum, azt már a hívó létrehozta,, így  az msg = no; sor  esetében a egy olyan objektum mutatót ad vissza a példa eljárás ami a példa eljárás futása után megsemmisül, viszont az msg.payload esetében létrejön az objektum a payload tulajdonság által mutatott címen, ami nem  seemisül meg a példa ejárás futása után, mivel az a hyvó eljárás msg payload tulajdonság "objektuma"?
    Mutasd a teljes hozzászólást!
  • Bár azt már nem értem, ha ezt a mutatót a return-ba visszaadom akkor miért csak az első elemet éri el a következő node

    Ez valami node-red-specifikus dolog lehet. A tömb is egyfajta objektum, nem fogja neked a JS motor "kicsomagolni" vagy feldarabolni, mielőtt visszatérne vele. A tömb része az elemszáma is, ez nem úgy megy mint C-ben hogy külön kell a kezdőcímet és a hosszat átadni.

    Esetleg az objektum megsemmisül, mivel azt a példa eljárásban hoztuk létre és a return után megsemmisül az eredeti objektum?

    Nem semmisül meg, lásd lentebb.

    Még pont azt akartam kérdezni, hogy mi semmisíti meg az objektumot.

    A hulladékgyűjtő (garbage collector vagy röviden GC), amikor már garantáltan senki sem tud hozzáférni. Javascriptben nem lehetséges "kézzel" felszabadítani egy objektumot, kizárólag úgy szűnhet meg, hogy elérhetetlenné válik, és a hulladékgyűjtő szabadítja fel. Ez megszünteti az olyan hibalehetőségeket, mint a dupla felszabadítás vagy a felszabadítás utáni használat, illetve a memóriaszivárgás egyszerűbb eseteit is megszünteti.
    Mutasd a teljes hozzászólást!
  • Még egyszer köszönöm a seítséget.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd