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 *
Pouze pokus:
if(test['bbb'] && test['bbb']['ccc']) 
radas
Profil *
na ověřování pole je f-ce is_array
CC
Profil *
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 *
omlouvám se...nevšiml jsem si že je to v JS
Witiko
Profil
Co třeba if("bbb" in test && "ccc" in test.bbb) aby to tu nebylo tak fádně jednotvárné? :-)
_es
Profil
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
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
Witiko:
Funguje aj zápis:
0 in array; // true
0 in object; // true
Možno pri poliach nenastáva prevod na text.
Witiko
Profil
_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í. :-)
_es
Profil
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
_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
_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
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"
V poslednom príkaze je nekompatibilná Opera.
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
_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!"
Navíc - jak jsem podotýkal již v předchozím příspěvku - bavíme se tu nyní pouze o API úrovni javascriptu, která může být značně nevypovídající ohledně toho "co se děje pod kapotou". Otázkou je jak a jestli vůbec jsou segmenty pole následně ukládány do hashové tabulky stejně jako atributy veškerých ostatních objektů. A zde se obávám se bez implementačního doporučení pro ECMAScript neobejdeme.
_es
Profil
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
_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.
Witiko
Profil
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
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
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

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: