Λάθη JavaScript


Πίνακας περιεχομένων

    Εμφάνιση πίνακα περιεχομένων


Αυτό το κεφάλαιο επισημαίνει ορισμένα κοινά λάθη JavaScript.


Κατά λάθος χρήση του χειριστή ανάθεσης

Τα προγράμματα JavaScript ενδέχεται να δημιουργήσουν απροσδόκητα αποτελέσματα εάν ένας προγραμματιστής χρησιμοποιεί κατά λάθος έναν τελεστή ανάθεσης (=), αντί για έναν τελεστή σύγκρισης (==) σε μια πρόταση if.

Αυτή η δήλωση if επιστρέφει false (ως αναμενόμενο) γιατί το x είναι δεν ισούται με 10:

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

Δοκιμάστε το μόνοι σας →

<!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>

Αυτή η δήλωση if επιστρέφει αληθής (ίσως όχι όπως αναμενόταν), γιατί το 10 είναι αληθής:

let x = 0;
if (x = 10)

Δοκιμάστε το μόνοι σας →

<!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>

Αυτή η δήλωση if επιστρέφει false (ίσως όχι όπως αναμενόταν), γιατί το 0 είναι ψευδής:

let x = 0;
if (x = 0)

Δοκιμάστε το μόνοι σας →

<!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>

Μια ανάθεση επιστρέφει πάντα την αξία της ανάθεσης.


Αναμένοντας χαλαρή σύγκριση

Σε τακτική σύγκριση, ο τύπος δεδομένων δεν έχει σημασία. Αυτή η δήλωση if επιστρέφει αληθής:

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

Δοκιμάστε το μόνοι σας →

<!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>

Σε αυστηρή σύγκριση, ο τύπος δεδομένων έχει σημασία. Αυτή η δήλωση if επιστρέφει ψευδής:

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

Δοκιμάστε το μόνοι σας →

<!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>

Είναι συνηθισμένο λάθος να ξεχνάμε ότι οι δηλώσεις switch χρησιμοποιούν αυστηρές σύγκριση:

Αυτός ο διακόπτης θήκης θα εμφανίσει μια ειδοποίηση:

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

Δοκιμάστε το μόνοι σας →

<!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>

Αυτός ο διακόπτης θήκης δεν θα εμφανίζει ειδοποίηση:

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

Δοκιμάστε το μόνοι σας →

<!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>


Μπερδεμένη προσθήκη και συνένωση

Η Προσθήκη αφορά την προσθήκη αριθμών.

Η Σύνδεση αφορά την προσθήκη συμβολοσειρών.

Στο JavaScript και οι δύο λειτουργίες χρησιμοποιούν τον ίδιο τελεστή +.

Εξαιτίας αυτού, η προσθήκη ενός αριθμού ως αριθμού θα παράγει διαφορετικό προκύπτει από την προσθήκη ενός αριθμού ως συμβολοσειρά:

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

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

Δοκιμάστε το μόνοι σας →

<!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>

Όταν προσθέτετε δύο μεταβλητές, μπορεί να είναι δύσκολο να προβλέψετε το αποτέλεσμα:

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"

Δοκιμάστε το μόνοι σας →

<!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>

Παρεξήγηση Floats

Όλοι οι αριθμοί στο JavaScript αποθηκεύονται ως Αριθμοί κινητής υποδιαστολής 64 bit (Επιπλέει).

Όλες οι γλώσσες προγραμματισμού, συμπεριλαμβανομένου του JavaScript, έχουν δυσκολίες ακριβείς τιμές κινητής υποδιαστολής:

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

Δοκιμάστε το μόνοι σας →

<!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>

Για την επίλυση του παραπάνω προβλήματος, βοηθά ο πολλαπλασιασμός και η διαίρεση:

Παράδειγμα

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

Δοκιμάστε το μόνοι σας →

<!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>


Σπάζοντας μια συμβολοσειρά JavaScript

Η JavaScript θα σας επιτρέψει να σπάσετε μια δήλωση σε δύο γραμμές:

Παράδειγμα 1

let x =
"Hello World!";

Δοκιμάστε το μόνοι σας →

<!DOCTYPE html>
<html>
<body>

<h2>Breaking a JavaScript Statement</h2>

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

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

</body>
</html>

Όμως, το σπάσιμο μιας δήλωσης στη μέση μιας συμβολοσειράς δεν θα λειτουργήσει:

Παράδειγμα 2

let x = "Hello
World!";

Δοκιμάστε το μόνοι σας →

<!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>

Πρέπει να χρησιμοποιήσετε μια "πίσω κάθετο" εάν πρέπει να σπάσετε μια πρόταση σε μια συμβολοσειρά:

Παράδειγμα 3

let x = "Hello \
World!";

Δοκιμάστε το μόνοι σας →

<!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>

Εσφαλμένη τοποθέτηση ερωτηματικών

Λόγω ενός άστοχου ερωτηματικού, αυτό το μπλοκ κώδικα θα εκτελεστεί ανεξάρτητα από το η τιμή του x:

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

Δοκιμάστε το μόνοι σας →

<!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>

Σπάζοντας μια δήλωση επιστροφής

Είναι μια προεπιλεγμένη συμπεριφορά JavaScript να κλείνει μια δήλωση αυτόματα στο τέλος μιας γραμμής.

Εξαιτίας αυτού, αυτά τα δύο παραδείγματα θα επιστρέψουν το ίδιο αποτέλεσμα:

Παράδειγμα 1

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

Δοκιμάστε το μόνοι σας →

<!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>

Παράδειγμα 2

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

Δοκιμάστε το μόνοι σας →

<!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 θα σας επιτρέψει επίσης να σπάσετε μια δήλωση σε δύο γραμμές.

Εξαιτίας αυτού, το παράδειγμα 3 θα επιστρέψει επίσης το ίδιο αποτέλεσμα:

Παράδειγμα 3

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

Δοκιμάστε το μόνοι σας →

<!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>

Αλλά, τι θα συμβεί εάν σπάσετε τη δήλωση επιστροφής σε δύο γραμμές όπως Αυτό:

Παράδειγμα 4

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

Δοκιμάστε το μόνοι σας →

<!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>

Η συνάρτηση θα επιστρέψει απροσδιόριστο!

Γιατί; Επειδή η JavaScript νόμιζε ότι εννοούσατε:

Παράδειγμα 5

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

Δοκιμάστε το μόνοι σας →

<!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>

Εξήγηση

Αν μια δήλωση είναι ελλιπής όπως:

let

Η JavaScript θα προσπαθήσει να ολοκληρώσει τη δήλωση διαβάζοντας την επόμενη γραμμή:

 power = 10;

Επειδή όμως αυτή η δήλωση είναι πλήρης:

 return

Το JavaScript θα το κλείσει αυτόματα ως εξής:

 return;

Αυτό συμβαίνει επειδή το κλείσιμο (τελικής) δηλώσεων με ερωτηματικό είναι προαιρετικό JavaScript.

Η JavaScript θα κλείσει τη δήλωση επιστροφής στο τέλος της γραμμής, επειδή είναι μια πλήρης δήλωση.

Ποτέ μην παραβιάζετε μια δήλωση επιστροφής.


Πρόσβαση σε Πίνακες με Επώνυμα Ευρετήρια

Πολλές γλώσσες προγραμματισμού υποστηρίζουν πίνακες με επώνυμα ευρετήρια.

Οι πίνακες με ονομασμένους δείκτες ονομάζονται συσχετιστικοί πίνακες (ή κατακερματισμοί).

Η JavaScript δεν υποστηρίζει πίνακες με ονομασμένα ευρετήρια.

Στο JavaScript, οι πίνακες χρησιμοποιούν αριθμημένα ευρετήρια:

Παράδειγμα

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"

Δοκιμάστε το μόνοι σας →

<!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>

Στο JavaScript, τα αντικείμενα χρησιμοποιούν επώνυμα ευρετήρια.

Εάν χρησιμοποιείτε ένα ευρετήριο με όνομα, κατά την πρόσβαση σε έναν πίνακα, η JavaScript θα επαναπροσδιορίσει ο πίνακας σε ένα τυπικό αντικείμενο.

Μετά τον αυτόματο επαναπροσδιορισμό, οι μέθοδοι και οι ιδιότητες του πίνακα θα παράγουν απροσδιόριστες ή λανθασμένα αποτελέσματα:

Παράδειγμα :

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

Δοκιμάστε το μόνοι σας →

<!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>


Τερματισμός ορισμών με κόμμα

Τα τελικά κόμματα στον ορισμό αντικειμένου και πίνακα είναι νόμιμα στο ECMAScript 5.

Παράδειγμα αντικειμένου:

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

Παράδειγμα πίνακα:

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

ΠΡΟΕΙΔΟΠΟΙΗΣΗ!!

Ο Internet Explorer 8 θα διακοπεί.

Το JSON δεν επιτρέπει κόμματα στο τέλος.

JSON:

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

JSON:

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

Το Undefined είναι Not Null

Τα αντικείμενα, οι μεταβλητές, οι ιδιότητες και οι μέθοδοι JavaScript μπορούν να ακαθορισμένα.

Επιπλέον, τα κενά αντικείμενα JavaScript μπορούν να έχουν την τιμή null.

Αυτό μπορεί να κάνει λίγο δύσκολο τον έλεγχο εάν ένα αντικείμενο είναι κενό.

Μπορείτε να ελέγξετε εάν υπάρχει ένα αντικείμενο δοκιμάζοντας εάν ο τύπος είναι μη καθορισμένος:

Παράδειγμα :

if (typeof myObj === "undefined") 

Δοκιμάστε το μόνοι σας →

<!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>

Αλλά δεν μπορείτε να ελέγξετε εάν ένα αντικείμενο είναι null, γιατί αυτό θα προκαλέσει σφάλμα εάν Το αντικείμενο είναι απροσδιόριστο:

Ανακριβής:

if (myObj === null)  

Για να λύσετε αυτό το πρόβλημα, πρέπει να ελέγξετε εάν ένα αντικείμενο δεν είναι null, και όχι απροσδιόριστο.

Αλλά αυτό μπορεί να δημιουργήσει ένα σφάλμα:

Ανακριβής:

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

Εξαιτίας αυτού, πρέπει να ελέγξετε για μη απροσδιόριστο για να μπορέσετε δοκιμή για μη null:

Σωστός :

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

Δοκιμάστε το μόνοι σας →

<!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>