Autor | Zpráva | ||
---|---|---|---|
CC Profil * |
Pokud mám například tohle
if(test['bbb']) dělej něco tak to funguje ale pokud potřebuju zkontrolovat jestli existuje i pole v tom poli: if(test['bbb']['ccc']) dělej něco tak to funguje pouze v případě pokud je nastavené to pole bbb, takže aby to fungovalo, musím to dělat takhle: if(test['bbb']) if(test['bbb']['ccc']) dělej něco Nejde to nějak udělat abych to nemusel dělat přes tu dvojpodmínku? |
||
Anonymní Profil * |
#2 · Zasláno: 28. 4. 2011, 12:09:24
Pouze pokus:
if(test['bbb'] && test['bbb']['ccc']) |
||
radas Profil * |
#3 · Zasláno: 28. 4. 2011, 12:19:06
na ověřování pole je f-ce is_array
|
||
CC Profil * |
#4 · Zasláno: 28. 4. 2011, 12:24:08
Taková funkce v JS není, ale to co kontroluju stejně array není, v tom je už uložený přímo řetězec, ne další pole
|
||
radas Profil * |
#5 · Zasláno: 28. 4. 2011, 12:56:14
omlouvám se...nevšiml jsem si že je to v JS
|
||
Witiko Profil |
#6 · Zasláno: 28. 4. 2011, 16:05:12
Co třeba if("bbb" in test && "ccc" in test.bbb) aby to tu nebylo tak fádně jednotvárné? :-)
|
||
_es Profil |
#7 · Zasláno: 28. 4. 2011, 16:15:47 · Upravil/a: _es
Ešte ide o to, že
test['bbb']['ccc'] môže existovať, no mať hodnotu false , undefined , 0 , atď.
Ak by sa malo testovať len to, či vlastnosť existuje, tak je správny Witikov test. Witiko: „aby to tu nebylo tak fádně jednotvárné“ Tak to tiež ešte spestrím: try{if("ccc" in test['bbb']) dělej něco}catch(e){} CC: „jestli existuje i pole v tom poli“ Ty nepoužívaš polia, ale objekty, akým spôsobom definuješ tie „polia“? |
||
Witiko Profil |
#8 · Zasláno: 28. 4. 2011, 17:17:58 · Upravil/a: Witiko
Když už se tu bavíme o polích, před časem mě něco málo zaujalo:
var array = []; array[0] = true; var object = {0: true}; "0" in array; // true "0" in object; // true Znamená to, že název vlastnosti objektu se projede .toString() metodou? U ostatních objektů to není tak zarážející, když jsou v paměti reprezentovány jako hash tabulky, nicméně u polí jsem čekal nějakou efektivnější metodu ukládání jednotlivých segmentů než pod čísla reprezentovaná jako text. |
||
_es Profil |
#9 · Zasláno: 28. 4. 2011, 17:37:45
Witiko:
Funguje aj zápis: 0 in array; // true 0 in object; // true |
||
Witiko Profil |
#10 · Zasláno: 28. 4. 2011, 17:51:35 · Upravil/a: Witiko
_es:
„Možno pri poliach nenastáva prevod na text.“ Já vždy tak nějak předpokládal že ne, nicméně po stránce logiky javascriptových objektů a konvencí pro názvy jejich atributů (nesmí začínat číslem) by jen dávalo smysl, kdyby se veškeré názvy převedly na řetězec. Ze strany javascriptu se to bude asi zjišťovat těžko, jelikož jde o jazyk prolezlý ducktypingem - to bohužel činí i výše zmíněný příklad neprůkazným, operátor in by také mohl volat .toString() dodaného objektu před samotným testováním. Pro úplnou jistotu bude nejspíš třeba sehnat si doporučení pro implementaci jazyka, nebo něco v tom stylu. Jen mě zajímalo, jestli to náhodou někdo neví. :-) |
||
Časová prodleva: 5 dní
|
|||
_es Profil |
#11 · Zasláno: 3. 5. 2011, 13:46:31
Witiko:
„smysl, kdyby se veškeré názvy převedly na řetězec.“ Pri poliach nastáva v určitých prípadoch naopak dokázateľne prevod na číslo: javascript:var p=[]; p["9"]=0; alert(p.length) |
||
Witiko Profil |
#12 · Zasláno: 4. 5. 2011, 16:28:02 · Upravil/a: Witiko
_es:
To dokazuje jen jednu věc a sice to, že název atibutu objektu je vždy před vyhodnocením převeden na řetězec. Těžko se dá ale zjistit, jak bude hodnota u polí nízkoúrovňově skutečně uložena. Nejspíš by nad tím člověk u vysokoúrovňového jazyka jako javascript neměl přemýšlet, ale mě to zajímá. Ukládání hodnot do hashové tabulky by sice rozlišování na String / Number nevyžadovalo, jelikož by byly obě hodnoty převedeny na číselný hash, nicméně pro případ řešení kolizí bych tipoval, že původní název bude uložen spolu s hodnotou pro účel kontroly, zda se načítá správná hodnota. Otázkou je v jakém formátu tento název pak je ukládán (číslo či řetězec) / zda je vůbec na ukládání jednotlivých položky pole využívána hashová tabulka. |
||
Witiko Profil |
#13 · Zasláno: 4. 5. 2011, 16:34:01
_es:
To dokazuje jen jednu věc a sice to, že název atibutu objektu je vždy před vyhodnocením převeden na řetězec. Tzn.: var objekt = {}, toString = {}; toString.toString = function() {return "test";}; objekt[toString] = "Testujeme"; objekt[toString] === objekt["test"]; // true To je myslím dostatečný důkaz toho, že v object[cokoliv] bude cokoliv vždy prohnáno metodou cokoliv.prototype.toString(). Těžko se dá ale zjistit, jak bude hodnota u polí nízkoúrovňově skutečně uložena. Nejspíš by nad tím člověk u vysokoúrovňového jazyka jako javascript neměl přemýšlet, ale mě to zajímá. Ukládání hodnot do hashové tabulky by sice rozlišování na String / Number nevyžadovalo, jelikož by byly obě hodnoty převedeny na číselný hash, nicméně pro případ řešení kolizí bych tipoval, že původní název bude uložen spolu s hodnotou pro účel kontroly, zda se načítá správná hodnota. Otázkou je v jakém formátu tento název pak je ukládán (číslo či řetězec) / zda je vůbec na ukládání jednotlivých položky pole využívána hashová tabulka. |
||
_es Profil |
#14 · Zasláno: 4. 5. 2011, 17:20:37
Witiko:
„To je myslím dostatečný důkaz toho, že v object[cokoliv] bude cokoliv vždy prohnáno metodou cokoliv.prototype.toString().“ Tie predchádzajúce „ukážkové“ kódy si nejako komplikovane domotal a nedokazujú vôbec nič. Napríklad tento príklad priamo dokazuje opak: var p = [1,2,3]; p.test="hodnota vlastnosti test"; Number.prototype.toString=function(){return "test";}; alert(p[0]); // 1 var i=0; alert(p[i]); // 1 var x = new Number(0); alert(p[x]); // "hodnota vlastnosti test" Dokonca ani zamenenie poľa za objekt {0:1,1:2,2:3} nespôsobí v prvých dvoch výpisoch použitie metódy toString z prototypu.
|
||
Witiko Profil |
#15 · Zasláno: 4. 5. 2011, 19:37:37 · Upravil/a: Witiko
_es:
To je ale zase věc rozdílu mezi základními datovými hodnotami a jejich objektovými protějšky. Tzn. string a String, number a Number. Jak jasně ukazuje Tvůj příklad 3, tak s objekty je zacházeno tak, jak jsem říkal - tzn. jsou prohnány toStringem. 0 je pouze základní datový typ, který bez použití operátoru tečky nemá potřebu jakkoliv se tvářit jako objekt či oběť prototypové dědičnosti. Viz.: Number.prototype.toString = function() {return "Hallelujah!"}; "Zpíváme " + (1) !== "Zpíváme Hallelujah!" |
||
_es Profil |
#16 · Zasláno: 4. 5. 2011, 19:50:22 · Upravil/a: _es
Witiko:
„Tzn. string a String, number a Number. Jak jasně ukazuje Tvůj příklad 3, tak s objekty je zacházeno tak, jak jsem říkal - tzn. jsou prohnány toStringem.“ Tvrdil si, že: „v object[cokoliv] bude cokoliv vždy prohnáno metodou cokoliv.prototype.toString()“ No v tom kóde, čo som dal ukážku, je pre cokoliv=0 p[0] niečo iné ako p[(0).prototype.toString()] , takže to tvoje tvrdenie neplatí.
Dávať do tých hranatých zátvoriek objekty asi aj tak nemá veľmi zmysel. „0 je pouze základní datový typ, který bez použití operátoru tečky nemá potřebu jakkoliv se tvářit jako objekt či oběť prototypové dědičnosti.“ Čísla - základný dátový typ, sa v JS veľmi radi tvária v prípade potreby ako objekty, inak by nefungovalo napríklad (15).toExponential() . Alebo sa dá do objektu Number.prototype pridať hocijaká metóda priamo použiteľná na čísla, či číselné premenné.
|
||
Witiko Profil |
#17 · Zasláno: 4. 5. 2011, 20:06:14 · Upravil/a: Witiko
_es:
„Tvrdil si, že“ Také jsem v minulém příspěvku uznal, že se dané "pravidlo" vztahuje pouze na objekty. Poměrně logicky chce javascript jako název atributu řetězec, na základní datové objekty se ale při převodu viditelně uplatňují jiná pravidla než u objektů. Jinak by příklad z mého minulého příspěvku [#15] měl jiný výstup. Co tím chci říct je, že viditelně javascript při automatickém převodu čísel na řetězec ignoruje toString metodu prototypu Number. Příklad z příspěvku [#15] toto prakticky dokazuje, o tom snad není sporu. „sa v JS veľmi radi tvária v prípade potreby ako objekty“ Vždyť přeci jasně píšu "bez použití operátoru tečky". :-) Vím, že Number prototype je rozšiřitelný (stojí na tom i jedna má matematická knihovna) - to nic nemění na tom, že samotné číslo se netváří jako objekt dokud nemusí - tedy dokud není použit operátor tečky / složených závorek - dokud zde není syntaktická iniciativa o práci s daným číslem jako s objektem. Bavíme se tu ale o podružných věcech. Stále se nedotýkáme problému jakým způsobem jsou segmenty javascriptových polí skutečně reprezentovány v paměti. |
||
Časová prodleva: 3 dny
|
|||
Witiko Profil |
#18 · Zasláno: 7. 5. 2011, 18:02:46 · Upravil/a: Witiko
Následující příklad využívající duck-typingovosti javascriptu poukazuje na to, že pravděpodobně jsou jednotlivé segmenty pole ukládány skutečně pod stringové hodnoty jako u veškerých ostatních objektů:
var a = { "0": "text1", "length": 1 }, b = { "0": "text2", "length": 1 }; alert( Array.prototype.concat.call( Array.prototype.slice.call(a, 0), Array.prototype.slice.call(b, 0) ).toString() ); // "text1, text2" |
||
_es Profil |
#19 · Zasláno: 7. 5. 2011, 21:08:20
Witiko:
„pravděpodobně jsou jednotlivé segmenty pole ukládány skutečně pod stringové hodnoty jako u veškerých ostatních objektů“ Ale žiadne pole tam predsa nepoužívaš. Rovnako môže byť použitý prevod opačný. |
||
Witiko Profil |
#20 · Zasláno: 8. 5. 2011, 11:12:35 · Upravil/a: Witiko
Ok, začetl jsem se do ECMA specifikace a tam je to černé na bílém. P tedy property je vždy interní metodě [[Put]] předávána jako String a převede se na Number jen za účelem zjištění, jedná-li se o segment pole a pro případný přepočet jeho délky. Na převod se nepoužívá Number.prototype.toString nýbrž interní metoda ToUint32. Hodnota je následně uložena stejným způsobem jako atribut prostého objektu. Viz.: http://interglacial.com/javascript_spec/a-15.html#a-15.4.5.1
|
||
Časová prodleva: 13 let
|
0