Přejít k navigační liště

Zdroják » Zprávičky » Když osm není osm: Pozor na vyhodnocování čísel v JavaScriptu

Když osm není osm: Pozor na vyhodnocování čísel v JavaScriptu

Představte si, že ošetříte pole ve formuláři na webové stránce pomocí JavaScriptu tak, aby uživatel musel zadat celé číslo větší než nula. Jako příklad si můžeme vzít třeba pole pro zadání měsíce (1–12). Abyste uživateli ušetřili práci, vyhodnotíte vložený údaj pomocí parseInt() a pokud bude hodnota mimo zadaný interval, nedovolíte formulář odeslat. Jde o jednoduchou funkci, každý ji bez problémů dokáže napsat, při testech vše funguje tak jak má, až při předání zákazníkovi se začnou množit stížnosti na to, že nelze odeslat formulář, i když je všechno vyplněné správně.

Možná příčina je ve funkci parseInt. Schválně, zkuste si tipnout, co v JavaScriptu vypíše následující kód:

function test(x) {
    document.write("'" + x + "' = ");
    document.write(parseInt(x));
    document.write("

");
}
test("01");
test("02");
test("07");
test("08");
test("09");

Možná vás to překvapí (i když by nemělo!), ale výsledek bude vypadat takto:

'01' = 1
'02' = 2
'07' = 7
'08' = 0
'09' = 0

(Můžete si otestovat)

Stačí pak, aby uživatel do pole pro měsíc nezadal „8“, ale „08“, a bude chováním velmi překvapen (navíc když mu zadání „07“ prošlo bez problémů…) Příčina je, jak už jistě tušíte, v tom, že JS parser používá syntaxi čísel z C, kde číslo, které začíná znakem „0“, je zapsáno v osmičkové soustavě.

Jak se vyhnout podobným problémům, a to rovnou několika různými způsoby, ukazuje Thomas Fuchs v článku Adventures in JavaScript number parsing.

Komentáře

Odebírat
Upozornit na
guest
6 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
Zobrazit všechny komentáře
kkl2401

Ono je to trochu složitější, jak člověk ostatně zjistí, když si zmíněnou ukázku vyzkouší ve větším množství prohlížečů; například v Opeře to dopadne „dobře“.
Ve skutečnosti je to tak, že soucasna specifikace ECMA-262 (http://www.ecma-international.org/publications/standards/Ecma-262.htm) ve sve pate edici jasne hovori o tom, ze pokud funkci parseInt neni druhy parametr (ciselna soustava) predan a pokud retezec nezacina (az na bile znaky) „0X“ (nebo „0ד), bere se jako ciselna soustava ta desitkova. Predchozi, treti edice, hovorila o tom, ze pripady zminene ve zpravicce prohlizec muze (ale nemusi!) interpretovat jako oktalova cisla. Podobne o tom mluvi popis JavaScriptu 1.5 (https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/parseInt): „If the input string begins with „0“, radix is eight (octal). Although widespread, this feature is specified as implementation dependent; always use a base for consistent results.“
Jinymi slovy kazdopadne je rozumne vzdy druhy parametr uvest, nicmene neni pravda to, ze kdyz to clovek neudela, tak budou ta cisla vsude vnimana oktalove, ani na to se nelze spolehat.

spud

Zajímavé, s tím jsem se ještě nesetkal a asi by mě to docela zaskočilo (už v JS dlouho nedělám). Dřív jsem ale většinou používal alternativní převody na číslo – vynásobením 1, na string – přičtením prázdného znaku.
Když jsem zkusil příklad z články upravit „po staru“ tak to fungovalo jak mělo.
var x = ‚08‘;
var y = x * 1;
document.write(„‚“+ x +“‘ = “ + y);
vysledek je ‚08‘ = 8

šachy

Ono by to šlo obejít také podmínkou
if(x.charAt(0)==„0“)
x=x.substring(1,x­.length)
Ikdyž souhlasím že nejjednodušší je vynásobení *1.

KarelI

Prominte, ale to je vzorova takyoprava od takyprogramatora, ktery nejdriv pise a pak mozna premysli. Takovych pripadu je na http://thedailywtf.com mraky. Co se stane, kdyz tech nul bude vic nebo kdyz tam bude mezera?

DevelX

Existuje jednoduché riešenie: použiť druhý argument, ktorý vynúti zvolenú číselnú sadu, takže potom sa parseInt(‚09‘, 10) vyhodnotí ako 9.

100% Lenin

Tak to dělá skutečný programátor a ne slizovač smetánky :D

GPUI Component: moderní Rust GUI komponenty pro cross-platform desktop aplikace

Různé
Komentáře: 0
GPUI Component je open-source Rust knihovna rozšiřující framework GPUI o více než 60 moderních, nativních a multiplatformních UI komponent. Staví na deklarativním přístupu, stateless renderování a jednoduchém API inspirovaném Reactem či Yew. Díky optimalizovanému výkonu, podpoře témat a flexibilním layoutům umožňuje rychlý vývoj desktopových aplikací, jako je například trading nástroj Longbridge Pro. Knihovna je licencována pod Apache 2.0 a dostupná na GitHubu.

Vitest 4.0 – nové vizuální testování, lepší debugging a stabilní Browser Mode

Nová verze Vitest 4.0 posouvá hranice testování webových aplikací. Přináší stabilní běh testů přímo v prohlížeči, podporu vizuálního regresního testování i chytřejší práci s lokátory a typováním. Vývojáři tak získávají robustnější, rychlejší a přehlednější nástroje pro zajištění kvality UI i logiky aplikací.