Распространенные ошибки JavaScript
В этой главе описаны некоторые распространенные ошибки JavaScript.
Случайное использование оператора присваивания
Программы JavaScript могут генерировать неожиданные результаты, если программист случайно использует оператор присваивания ( =
) вместо оператора сравнения ( ==
) в операторе if.
Этот if
оператор возвращает false
(как и ожидалось), потому что x не равно 10:
let x = 0;
if (x == 10)
Этот if
оператор возвращает true
(возможно, не так, как ожидалось), потому что 10 верно:
let x = 0;
if (x = 10)
Этот if
оператор возвращает false
(возможно, не так, как ожидалось), потому что 0 ложно:
let x = 0;
if (x = 0)
Присваивание всегда возвращает значение присваивания.
Ожидание свободного сравнения
При обычном сравнении тип данных не имеет значения. Это if
утверждение возвращает истину:
let x = 10;
let y = "10";
if (x == y)
В строгом сравнении тип данных имеет значение. Это if
утверждение возвращает ложь:
let x = 10;
let y = "10";
if (x === y)
Распространенной ошибкой является забывание того, что switch
операторы используют строгое сравнение:
Это case switch
отобразит предупреждение:
let x = 10;
switch(x) {
case 10: alert("Hello");
}
Это case switch
не будет отображать предупреждение:
let x = 10;
switch(x) {
case "10": alert("Hello");
}
Запутанное сложение и конкатенация
Сложение — это добавление чисел .
Конкатенация — это добавление строк .
В JavaScript обе операции используют один и тот же +
оператор.
Из-за этого добавление числа в виде числа даст результат, отличный от добавления числа в виде строки:
let x = 10;
x = 10 + 5; //
Now x is 15
let y = 10;
y += "5";
// Now y is "105"
При добавлении двух переменных может быть трудно предугадать результат:
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"
Непонимание поплавков
Все числа в JavaScript хранятся как 64- битные числа с плавающей запятой (Floats).
Все языки программирования, включая JavaScript, имеют трудности с точными значениями с плавающей запятой:
let x = 0.1;
let y = 0.2;
let z = x + y
// the result in z will not be 0.3
Чтобы решить проблему выше, это помогает умножить и разделить:
Пример
let z = (x * 10 + y * 10) / 10; // z will be 0.3
Разрыв строки JavaScript
JavaScript позволит вам разбить выражение на две строки:
Пример 1
let x =
"Hello World!";
Но сломать оператор в середине строки не получится:
Пример 2
let x = "Hello
World!";
Вы должны использовать «обратную косую черту», если вы должны разорвать оператор в строке:
Пример 3
let x = "Hello \
World!";
Неуместная точка с запятой
Из-за неуместной точки с запятой этот блок кода будет выполняться независимо от значения x:
if (x == 19);
{
// code block
}
Нарушение оператора возврата
По умолчанию JavaScript автоматически закрывает оператор в конце строки.
Из-за этого эти два примера вернут один и тот же результат:
Пример 1
function myFunction(a) {
let power = 10
return a * power
}
Пример 2
function myFunction(a) {
let power = 10;
return a * power;
}
JavaScript также позволяет разбивать оператор на две строки.
Из-за этого пример 3 также вернет тот же результат:
Пример 3
function myFunction(a) {
let
power = 10;
return a * power;
}
Но что произойдет, если вы разобьете оператор return на две строки следующим образом:
Пример 4
function myFunction(a) {
let
power = 10;
return
a * power;
}
Функция вернется undefined
!
Почему? Потому что JavaScript думал, что вы имели в виду:
Пример 5
function myFunction(a) {
let
power = 10;
return;
a * power;
}
Объяснение
Если утверждение неполное, например:
let
JavaScript попытается завершить оператор, прочитав следующую строку:
power = 10;
Но так как это утверждение завершено:
return
JavaScript автоматически закроет его следующим образом:
return;
Это происходит потому, что закрытие (окончание) операторов точкой с запятой не является обязательным в JavaScript.
JavaScript закроет оператор return в конце строки, потому что это завершенный оператор.
Никогда не нарушайте оператор возврата.
Доступ к массивам с именованными индексами
Многие языки программирования поддерживают массивы с именованными индексами.
Массивы с именованными индексами называются ассоциативными массивами (или хэшами).
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"
В 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
Окончание определений запятой
Завершающие запятые в определении объекта и массива допустимы в 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];
Неопределенный не равен нулю
Объекты, переменные, свойства и методы JavaScript могут быть undefined
.
Кроме того, пустые объекты JavaScript могут иметь значение null
.
Это может немного затруднить проверку, является ли объект пустым.
You can test if an object exists by testing if the type is undefined
:
Example:
if (typeof myObj === "undefined")
But you cannot test if an object is null
, because this will throw an error if the
object is undefined
:
Incorrect:
if (myObj === null)
To solve this problem, you must test if an object is not null
,
and not undefined
.
But this can still throw an error:
Incorrect:
if (myObj !== null && typeof myObj
!== "undefined")
Because of this, you must test for not undefined
before you can
test for not null
:
Correct:
if (typeof myObj !== "undefined" && myObj !== null)