JavaScript Распространенные ошибки
Эта глава указывает на некоторые распространенные ошибки JavaScript.
Случайное использование оператора присваивания
Программы JavaScript могут генерировать неожиданные результаты, если программист случайно использует оператор присваивания (=) вместо оператора сравнения (= =) в операторе if.
Эта инструкция If возвращает false (как ожидалось), поскольку x не равен 10:
var x = 0;
if (x == 10)
Эта инструкция If возвращает true (возможно, не так, как ожидалось), поскольку значение 10 равно true:
var x = 0;
if (x = 10)
Эта инструкция If возвращает false (возможно, не так, как ожидалось), поскольку значение 0 равно false:
var x = 0;
if (x = 0)
Назначение всегда возвращает значение назначения.
Ожидая свободного сравнения
При регулярном сравнении тип данных не имеет значения. Этот оператор If возвращает true:
var x = 10;
var y = "10";
if (x == y)
При строгом сравнении тип данных имеет значение. Эта инструкция If возвращает false:
var x = 10;
var y = "10";
if (x === y)
Часто ошибочно забывать, что операторы Switch используют строгое сравнение:
Этот переключатель case отобразит оповещение:
var x = 10;
switch(x) {
case 10: alert("Hello");
}
Этот переключатель case не будет отображать оповещение:
var x = 10;
switch(x) {
case "10": alert("Hello");
}
Запутанное сложение и сцепление
Дополнение о добавлении чисел.
Сцепление — это добавление строк.
В JavaScript обе операции используют один и тот же оператор +.
По этой причине добавление числа в качестве числа приведет к другому результату при добавлении числа в виде строки:
var x = 10 + 5; //
the result in x is 15
var x = 10 + "5";
// the result in x is "105"
При добавлении двух переменных может быть трудно предвидеть результат:
var x = 10;
var y = 5;
var z = x + y;
// the result in z is 15
var x = 10;
var y = "5";
var z =
x + y;
// the result in z is "105"
Недоразумение плавает
Все числа в JavaScript хранятся в виде чисел с плавающей запятой (Floating) в 64 бит.
Все языки программирования, включая JavaScript, испытывают трудности с точными значениями с плавающей запятой:
var x = 0.1;
var y = 0.2;
var z = x + y
// the result in z will not be 0.3
Чтобы решить проблему выше, она помогает умножить и разделить:
Пример
var z = (x * 10 + y * 10) / 10; // z will be 0.3
Разбиение строки JavaScript
JavaScript позволит вам разорвать заявление на две строки:
Пример 1
var x =
"Hello World!";
Но, нарушение оператора в середине строки не будет работать:
Пример 2
var x = "Hello
World!";
Необходимо использовать "обратную косую черту", если необходимо разорвать инструкцию в строке:
Пример 3
var x = "Hello \
World!";
Размещение точки с запятой
Из-за неместой точки с запятой этот блок кода будет выполняться независимо от значения x:
if (x == 19);
{
// code block
}
Нарушение оператора возврата
Это поведение по умолчанию JavaScript, чтобы закрыть инструкцию автоматически в конце строки.
Из-за этого эти два примера будут возвращать тот же результат:
Пример 1
function myFunction(a) {
var power = 10
return a * power
}
Пример 2
function myFunction(a) {
var power = 10;
return a * power;
}
JavaScript также позволит вам разорвать заявление на две строки.
Из-за этого пример 3 также вернет тот же результат:
Пример 3
function myFunction(a) {
var
power = 10;
return a * power;
}
Но что произойдет, если вы разорвать оператор return в двух строках, как это:
Пример 4
function myFunction(a) {
var
power = 10;
return
a * power;
}
Функция вернет undefined!
Почему? Потому что JavaScript считает, что вы имели в виду:
Пример 5
function myFunction(a) {
var
power = 10;
return;
a * power;
}
Объяснение
Если инструкция неполна, как:
var
JavaScript будет пытаться завершить инструкцию, читая следующую строку:
power = 10;
Но так как это заявление является полным:
return
JavaScript будет автоматически закрывать его так:
return;
Это происходит потому, что закрытие (окончание) операторов с точкой с запятой является необязательным в JavaScript.
JavaScript закроет оператор return в конце строки, поскольку он является полным оператором.
Never break a return statement.
Доступ к массивам с именованными индексами
Многие языки программирования поддерживают массивы с именованными индексами.
Массивы с именованными индексами называются ассоциативными массивами (или хэшами).
JavaScript не поддерживает массивы с именованными индексами.
В JavaScript массивы используют пронумерованные индексы:
Пример
var person = [];
person[0] = "John";
person[1] = "Doe";
person[2] = 46;
var x = person.length;
// person.length will return 3
var y = person[0];
// person[0] will return "John"
В JavaScript объекты используют именованные индексы.
Если вы используете именованный индекс, то при обращении к массиву JavaScript будет переопределять массив в стандартный объект.
После автоматического переопределения методы и свойства массива будут давать неопределенные или неверные результаты:
Пример:
var person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
var x = person.length; // person.length will
return 0
var y = 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];
Значение undefined не равно null
Объекты JavaScript, переменные, свойства и методы могут быть неопределенными.
Кроме того, пустые объекты JavaScript могут иметь значение null.
Это может немного усложнить тестирование, если объект пуст.
Можно проверить, существует ли объект путем тестирования, если тип не определен:
Пример:
if (typeof myObj === "undefined")
Но вы не можете проверить, если объект имеет значение NULL, потому что это приведет к ошибке, если объект не определен:
Неправильный:
if (myObj === null)
Чтобы устранить эту проблему, необходимо проверить, если объект не равен null, а не не определено.
Но это все еще может вызвать ошибку:
Неправильный:
if (myObj !== null && typeof myObj
!== "undefined")
По этой причине необходимо проверить для не undefined , прежде чем можно проверить не null:
Правильно:
if (typeof myObj !== "undefined" && myObj !== null)
Ожидаемая область уровня блока
JavaScript не создает новую область для каждого блока кода.
Это верно во многих языках программирования, но не верно в JavaScript.
Этот код будет отображать значение i (10), даже вне блока цикла for:
Пример
for (var i = 0; i <10; i++) {
// some code
}
return i;