Chyby v JavaScriptu


Obsah

    Zobrazit obsah


Tato kapitola poukazuje na některé běžné chyby JavaScriptu.


Náhodné použití operátora přiřazení

JavaScript programy mohou generovat neočekávané výsledky, pokud programátor omylem používá operátor přiřazení (=) místo operátoru porovnání (==) v příkazu if.

Tento příkaz if vrací false (jako očekáváno), protože x je nerovná se 10:

let x = 0;
if (x == 10) 

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Comparisons</h2>

<p>This returns false (as expected) because x is not equal to 10:</p>

<p id="demo"></p>

<script>
let x = 0;
document.getElementById("demo").innerHTML = Boolean(x == 10);
</script>

</body>
</html>

Tento příkaz if vrací true (možná ne podle očekávání), protože 10 je skutečný:

let x = 0;
if (x = 10)

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>This returns true (maybe not as expected), because 10 is true:</p>

<p id="demo"></p>

<script>
let x = 0;
document.getElementById("demo").innerHTML = Boolean(x = 10);
</script>

</body>
</html>

Tento příkaz if vrací false (možná ne podle očekávání), protože 0 je Nepravdivé:

let x = 0;
if (x = 0)

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>This if statement returns false (maybe not as expected), because 0 is false:</p>

<p id="demo"></p>

<script>
let x = 0;
document.getElementById("demo").innerHTML = Boolean(x = 0);
</script>

</body>
</html>

Přiřazení vždy vrátí hodnotu přiřazení.


Očekává se volné srovnání

Při běžném srovnání nezáleží na datovém typu. Tento příkaz if vrátí skutečný:

let x = 10;
let y = "10";
if (x == y) 

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>In regular comparison, data type does not matter. This if statement returns true:</p>

<p id="demo"></p>

<script>
let x = 10;
let y = "10";
document.getElementById("demo").innerHTML = Boolean(x == y);
</script>

</body>
</html>

V přísném srovnání záleží na datovém typu. Tento příkaz if vrátí hodnotu false:

let x = 10;
let y = "10";
if (x === y) 

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>In strict comparison, data type does matter. This if statement returns false:</p>

<p id="demo"></p>

<script>
let x = 10;
let y = "10";
document.getElementById("demo").innerHTML = Boolean(x === y);
</script>

</body>
</html>

Je běžnou chybou zapomínat, že příkazy switch používají striktní srovnání:

Tento přepínač případu zobrazí upozornění:

let x = 10;
switch(x) {
  case 10: alert("Hello");
    } 

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>It is a common mistake to forget that switch statements use strict comparison.</p>
<p>This will work:</p>

<p id="demo"></p>

<script>
let x = 10;
switch(x) {
  case 10: document.getElementById("demo").innerHTML = "Hello";
}
</script>

</body>
</html>

Tento přepínač případu nezobrazí upozornění:

let x = 10;
switch(x) {
  case "10": alert("Hello");
    } 

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>It is a common mistake to forget that switch statements use strict comparison.</p>
<p>This will not work:</p>

<p id="demo"></p>

<script>
let x = 10;
switch(x) {
  case "10": document.getElementById("demo").innerHTML = "Hello";
}
</script>

</body>
</html>


Matoucí sčítání a zřetězení

Sčítání je o přidávání čísel.

Zřetězení spočívá v přidávání řetězců.

V JavaScriptu obě operace používají stejný operátor +.

Z tohoto důvodu přidání čísla jako čísla vytvoří jiné výsledek přidání čísla jako řetězce:

let x = 10;
x = 10 + 5;       // 
    Now x is 15

let y = 10;
y += "5";        
    // Now y is "105"

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>Adding a number as a number produces a different result from adding a number as a string:</p>

<p id="demo"></p>

<script>
let y = 10
y += "5";
document.getElementById("demo").innerHTML = y;
</script>

</body>
</html>

Při přidávání dvou proměnných může být obtížné předvídat výsledek:

let x = 10;
let y = 5;
let z = x + y;     // Now z is 15

let x = 10;
let y = "5";
let z = x + y;     // Now z is "105"

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>Adding a number as a number produces a different result from adding a number as a string:</p>

<p id="demo"></p>

<script>
let x = 10;
let y = "5";
let z = x + y;
document.getElementById("demo").innerHTML = z;
</script>

</body>
</html>

Nedorozumění Floats

Všechna čísla v JavaScriptu jsou uložena jako 64bitová čísla s plovoucí desetinnou čárkou (Plováky).

Všechny programovací jazyky včetně JavaScriptu mají potíže přesné hodnoty s plovoucí desetinnou čárkou:

let x = 0.1;
let y = 0.2;
let z = x + y            
    // the result in z will not be 0.3

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>All programming languages, including JavaScript, have difficulties with precise floating point values:</p>

<p id="demo"></p>

<script>
let x = 0.1;
let y = 0.2;
let z = x + y;
document.getElementById("demo").innerHTML = z;
</script>

</body>
</html>

K vyřešení výše uvedeného problému pomáhá násobení a dělení:

Příklad

let z = (x * 10 + y * 10) / 10;       // z will be 0.3

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>All programming languages, including JavaScript, have difficulties with precise floating point values.</p>
<p>To solve the problem, it helps to multiply and divide:</p>

<p id="demo"></p>

<script>
let x = 0.1;
let y = 0.2;
let z = (x * 10 + y *10) / 10;
document.getElementById("demo").innerHTML = z;
</script>

</body>
</html>


Přerušení řetězce JavaScriptu

JavaScript vám umožní rozdělit příkaz na dva řádky:

Příklad 1

let x =
"Hello World!";

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Breaking a JavaScript Statement</h2>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML =
"Hello World!";
</script>

</body>
</html>

Ale porušení příkazu uprostřed řetězce nebude fungovat:

Příklad 2

let x = "Hello
World!";

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>
<p>Breaking a statement in the middle of a string will not work:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello 
World!";
</script>

</body>
</html>

Pokud musíte porušit příkaz v řetězci, musíte použít "zpětné lomítko":

Příklad 3

let x = "Hello \
World!";

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>You must use a "backslash" if you must break a statement in a string:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello \
World!";
</script>

</body>
</html>

Chybné umístění středníku

Kvůli špatně umístěnému středníku se tento blok kódu spustí bez ohledu na hodnota x:

if (x == 19);
{
    // code block  
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p id="demo"></p>

<script>
let x = 5;
if (x == 19);
{
document.getElementById("demo").innerHTML = "Hello";
}
</script>

</body>
</html>

Porušení prohlášení o vrácení

Jedná se o výchozí chování JavaScriptu, které automaticky zavírá příkaz na konec řádku.

Z tohoto důvodu tyto dva příklady vrátí stejný výsledek:

Příklad 1

function myFunction(a) {
    let power = 10  
  return a * power
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>This example will return a correct result:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  let power = 10
  return a * power
}
</script>

</body>
</html>

Příklad 2

function myFunction(a) {
    let power = 10;
  return a * power;
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>This example will return a correct result:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  let power = 10;
  return a * power;
}
</script>

</body>
</html>

JavaScript vám také umožní rozdělit příkaz na dva řádky.

Z tohoto důvodu příklad 3 také vrátí stejný výsledek:

Příklad 3

function myFunction(a) {
    let
  power = 10;  
  return a * power;
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>This example will return a correct result:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  let
  power = 10;
  return a * power;
}
</script>

</body>
</html>

Ale co se stane, když rozbijete příkaz return na dva řádky, jako je tento:

Příklad 4

function myFunction(a) {
    let
  power = 10;  
  return
  a * power;
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>This example will return undefined:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  let
  power = 10;
  return
  a * power;
}
</script>

</body>
</html>

Funkce vrátí undefined!

Proč? Protože JavaScript si myslel, že máte na mysli:

Příklad 5

function myFunction(a) {
    let
  power = 10;  
  return;
  a * power;
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>Common JavaScript Mistakes</h2>

<p>This example will return undefined:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  let
  power = 10;
  return;
  a * power;
}
</script>

</body>
</html>

Vysvětlení

Pokud je prohlášení neúplné, například:

let

JavaScript se pokusí dokončit prohlášení přečtením následujícího řádku:

 power = 10;

Ale protože toto prohlášení je úplné:

 return

JavaScript jej automaticky zavře takto:

 return;

Děje se tak proto, že uzavírací (koncové) příkazy středníkem je nepovinné JavaScript.

JavaScript zavře příkaz return na konci řádku, protože je to úplné prohlášení.

Nikdy neporušujte prohlášení o návratu.


Přístup k polím s pojmenovanými indexy

Mnoho programovacích jazyků podporuje pole s pojmenovanými indexy.

Pole s pojmenovanými indexy se nazývají asociativní pole (nebo hash).

JavaScript nepodporuje pole s pojmenovanými indexy.

V JavaScriptu pole používají číslované indexy:

Příklad

const person = [];
person[0] = "John";
person[1] = "Doe";
person[2] = 46;
person.length;       
 // person.length will return 3
person[0];           
 // person[0] will return "John"

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Arrays</h1>

<p id="demo"></p>

<script>
const person = [];
person[0] = "John";
person[1] = "Doe";
person[2] = 46; 
document.getElementById("demo").innerHTML =
person[0] + " " + person.length;
</script>

</body>
</html>

V JavaScriptu objekty používají pojmenované indexy.

Pokud použijete pojmenovaný index, JavaScript se při přístupu k poli předefinuje pole na standardní objekt.

Po automatické redefinici vytvoří metody a vlastnosti pole nedefinované resp nesprávné výsledky:

Příklad:

const person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
person.length;      // person.length will 
 return 0
person[0];          
 // person[0] will return undefined

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Arrays</h1>

<p>If you use a named index when accessing an array, JavaScript will redefine the array to a standard object, and some array methods and properties will produce undefined or incorrect results.</p>

<p id="demo"></p>

<script>
const person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46; 
document.getElementById("demo").innerHTML =
person[0] + " " + person.length;
</script>

</body>
</html>


Ukončení definic čárkou

Koncové čárky v definici objektu a pole jsou v ECMAScript 5 legální.

Příklad objektu:

person = {firstName:"John", lastName:"Doe", age:46,}

Příklad pole:

points = [40, 100, 1, 5, 25, 10,];

VAROVÁNÍ !!

Internet Explorer 8 se zhroutí.

JSON nepovoluje koncové čárky.

JSON:

person = {"firstName":"John", "lastName":"Doe", "age":46}

JSON:

points = [40, 100, 1, 5, 25, 10];

Nedefinováno není Null

Objekty, proměnné, vlastnosti a metody JavaScriptu mohou být nedefinované.

Prázdné objekty JavaScriptu mohou mít navíc hodnotu null.

To může trochu ztížit testování, zda je objekt prázdný.

Pokud objekt existuje, můžete otestovat, zda je typ nedefinovaný:

Příklad:

if (typeof myObj === "undefined") 

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Objects</h2>

<p>To test if an object does not exist, test if the type is undefined:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = typeof myObj === "undefined";
</script>

</body>
</html>

Nemůžete však otestovat, zda je objekt null, protože to způsobí chybu, pokud objekt je nedefinovaný:

Nesprávný:

if (myObj === null)  

Chcete-li tento problém vyřešit, musíte otestovat, zda objekt není null, a nikoli undefined.

Ale stále to může způsobit chybu:

Nesprávný:

if (myObj !== null && typeof myObj 
  !== "undefined")  

Z tohoto důvodu musíte nejprve otestovat, zda není undefined test, zda není null:

správně:

if (typeof myObj !== "undefined" && myObj !== null) 

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Objects</h2>

<p>If you want to test if an object is not null, you must test if it not undefined first.</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = typeof myObj !== "undefined" && myObj !== null;
</script>

</body>
</html>