JS Savet: Uslovno dodavanje svojstva na objektu
Često se javlja potreba da dodamo neko svojstvo objektu koje zavisi od nekog uslova.
const nickname = req.body.nick;
const formData = {
name: 'John',
}
if (nickname) {
formData['nickname'] = nickname;
}
Ovo je najčešći način za dodavanje svojstva objektu. Na ovaj način činimo da kôd bude manje čitljiv i definicija objekta (strukture) se dešava na više mesta.
ES6 u pomoć
Ako iskoristimo pametno "spread" operator možemo značajno da popravimo kôd.
const nickname = req.body.nick;
const formData = {
name: 'John',
...nickname && {nickname: nickname}
}
Ovim smo primetno skratili naš kôd i definicija strukture je na jednom mestu.
0
ili neki drugi broj koji je "false". Uslov može ovako da izgleda ...typeof zetoni === "number" && !isNaN(zetoni) && {zetoni},
Kako ovo radi
Prvo da se upoznamo sa &&
operatorom. Ako zagledamo malo u specifikaciju &&
operatora, možemo da vidimo da će vrednost biti jedna od vrednosti operatora.
&&
ne mora da bude boolean
tipa.
Ukoliko leva strana nije istinita, desna strana se neće evaluirati i rezultat operacije biće "false". I suprotno, desna strana će se evaluirati samo ako je leva strana istinita. Ovo znači da će naš "spread" operator dobiti levu vrednost false, ili desnu vrednost - objekat.
Kako ovo stvarno radi
Ovo je malo naprednije objašnjenje šta se stvarno dešava i oslanja se na poznavanje ECMA specifikacije. Gore nije objašnjeno šta se desi kada se nađe "number" ili "boolean" vrednost pored "spread" operatora.
Šta može da se nađe sa desne strane "spread" operatora?
null
iliundefined
Boolean
iNumber
Object
- Ovo je već poznato ponašanje
Kada pogledamo specifikaciju za "spread" operator vidimo da se pozove CopyDataProperties
operator. Gledajući šta radi CopyDataProperties
operator, možemo da vidimo da u koraku tri ako se nađe null
ili undefined
, operator neće uraditi ništa.
const obj = {
...null,
...undefined
}
console.log(obj) // {}
Ovim smo pokrili prvi slučaj, sada ostaje još drugi slučaj kad se nađu drugi tipovi koji nisu Object
.
Ako pogledamo četvrtu stavku CopyDataProperties
operatora, vidimo da se nad from
(desna strana) zove ToObject
. Što znači da će svaki tip biti obmotan u odgovarajući tip objekta. Ono što je bitno da znate je, da ovi objekti, Boolean
i Number
, sadrže nešto što se zovu interni slotovi. Ovim slotovima ne može da se pristupi već predstavljaju interno stanje objekta na nivou "engine"a. Slotovi u objektu se nazivaju između duplih uglastih zagrada [[imeSlota]]
.
console.log(new Number(17));
console.log(new Boolean(true));
/*
Number {23}
__proto__: Number
[[PrimitiveValue]]: 23
Boolean {true}
__proto__: Boolean
[[PrimitiveValue]]: true
*/
Primitivnim vrednostima ne možemo obično da pristupimo, već koristimo valueOf()
.
console.log(new Number(17).valueOf());
console.log(new Boolean(true).valueOf());
/*
17
true
*/
Ovo nama ide sve u prilog zato što objekat bez svojstva znači da CopyDataProperties
operator nema šta da kopira.
Pokrili smo sve slučajeve, tako da smo sigurni koja god vrednost da dođe kao uslov neće da napravi problem objektu.