Основные ошибки, допускаемые разработчиками JavaScript

Основные ошибки, допускаемые разработчиками JavaScript Сайтостроение

Основные ошибки, допускаемые разработчиками JavaScript

От создателя: JavaScript — это язык программирования, который дозволяет реализовывать на интернет-страницах сложные функции, и, если кратко, вы уже много понимаете о JS, потому что это самый пользующийся популярностью язык программирования в 2019 году (это не наше мировоззрение, все числа мы получили из Developer Survey 2019 от Stackoverflow). Если вы не слышали о этом опросе, вы должны ознакомиться с ним, до этого чем мы продолжим.

Так как JavaScript является основой хоть какого веб-приложения, мы не будем дискуссировать достоинства JS либо перечень его способностей. Заместо этого мы разглядим обычные ошибки, которые практически любой программер JS совершал за свою карьеру.

Основные ошибки, допускаемые разработчиками JavaScript

Согласно тому же опросу Stackoverflow, 41% программистов, принявших роль, имеют проф опыт написания кода наименее 5 лет.

Основные ошибки, допускаемые разработчиками JavaScript

Эта статья в главном создана для таковых разрабов. Новейшие создатели (0–2 года) могут отыскать в статье полезные примеры, поэтому что это нехороший код, из которого вы сможете извлечь уроки. Наиболее бывалые создатели (от 3 лет) могут улыбнуться, узнав ошибки, которые они совершали в прошедшем. В любом случае, потратив некое время на чтение данной статьи, вы получите или познания, или наслаждение. Услаждайся чтением!

Перечень ошибок:

Вы помните разницу меж «=», «==» и «===»?

Запамятовали о области деяния переменных?

Недопонимание различия меж «let», «const» и «var».

Неправильные ссылки на способы экземпляра.

Трудности использования this.

Вы помните разницу меж «=», «==» и «===»?

Быстрее всего, вы сталкивались с схожей неувязкой:

JavaScript

123456var x = 1;if (x = 7) {   alert(«Hello»); } else {  alert(«Nope»);}

И вы получали «Hello»! Почему? Ответ весьма прост: вы не осознаете разницу меж 3 операторами, упомянутыми выше. Это не непростая ошибка, и как вы поймете ее, вы навряд ли забудете о этом. Так как эта ошибка весьма ординарна, вы сможете пропустить ее, когда дело доходит до критерий выхода из цикла.

Давайте покончим с сиим и пойдем далее. «=» — это оператор равенства, потому он употребляется для присваивания. В нашем примере мы присваиваем «x» значение семь в условии и получаем слова приветствия «Hello».

Верный код смотрится так:

JavaScript

123456var x = 1;if (x == 7) {  alert(«Hello»);} else {  alert(«Nope»);}

Мы получаем «Nope».

«==» — оператор сопоставления. Почему? Поэтому что он дозволяет преобразовывать значения из 1-го типа в иной, чтоб сопоставить их. Даже если мы присваиваем x строковое значение «7» и сравниваем его с числовым значением «7», код возвращает нам «Hello». Но приведенный ниже код возвращает «Nope»:

Почему? Поэтому что «===» является оператором сопоставления серьезного равенства. Если этот оператор возвращает «true», это значит, что наши значения схожи как по значению, так и по типу. Для «===» есть аналог — способ Object.is. Он имеет некие различия в обработке значений -0, +0 и NaN, но некие из вас знают, каковы эти различия, в то время как остальные могут обратиться к управлению по JavaScript. И совершенно, рекомендуется:

Если у вас есть какие-либо сомнения относительно способов либо функций JS, вы постоянно сможете отыскать их в Гугл, но мы настоятельно советуем применять Управление по JavaScript.

Запамятовали о области видимости переменных?

Еще одна достаточно обычная ошибка:

JavaScript

1234567let arr = [1,2,3,4,5,6,7];var j;for (j=0;  j < arr.length; j++) {  console.log (arr[j]);} // …some long codeconsole.log ( j ); // we get the number “7”
READ
Шпаргалка по импорту и экспорту ES6

И просто запамятовать, что наша переменная меняет свое значение опосля цикла. Эта ошибка имеет пространство не только лишь в JS, да и в целом. В неких языках вы определяете переменную лишь снутри цикла, и она уничтожается опосля окончания цикла, но не в JavaScript.

И обратная ситуация, когда вы пытаетесь получить доступ к переменной, которая была определена в локальной области (это относится к области деяния функции). Пример:

JavaScript

1234function myFunction() {  var me = «You can’t touch me!»;} console.log(me);

«me» не определено, извините, вы сможете связаться со своим адвокатом либо просто уяснить область внедрения переменных в JavaScript. Верный код:

JavaScript

12345var me;function myFunction() {  me = «You can’t touch me!»;}console.log(me + ‘I Can, sorry’);

Очередной пример, связанный с главным словом let, введенным в JS в 2015 году для объявления переменных (ECMA Script 6):

JavaScript

12345let arr = [1,2,3,4,5,6,7];for (let j = 0; j < arr.length; j++) {  console.log(arr[j]); // the output: 1, 2, 3, 4, 5, 6, 7} console.log(j) // j = 0.

Ключевое слово let не изменило переменную «j» по сопоставлению с первым примером. И этот вопросец — тема нашего последующего раздела.

Недопонимание различия меж «let», «const» и «var»

Это тесновато соединено с предшествующей неувязкой, но, так как практически любой из нас гуглил «разница меж var, const и let», мы выделяем раздельно этот вопросец. Давайте поначалу поглядим на код ниже:

JavaScript

123console.log(x); // undefinedvar x = 5;console.log(x); // the output is 5

Код логичен как, и вывод, вопросцев нет. Иной пример:

JavaScript

123console.log(x); // Error: cannot access “x” before the initializationlet x = 5;console.log(x);

Причина в том, что var — это область деяния функции, а let — это область деяния блока. Когда вы объявляете переменную при помощи главного слова let, вы перемещаетесь в начало блока. Это может привести к ошибке ссылки при попытке доступа к переменной до инициализации.

Она именуется «временная мертвая зона», если вы желаете выяснить больше о ней, вы сможете посетить официальный сайт для разрабов JS Mozilla JavaScript Guide.

Но мы перебегаем к нашему последующему участнику и показываем пример, чтоб обрисовать все:

JavaScript

12345678910111213141516let a = 5;var b = 10;const c = 11; if (a === 5) {  let a = 4; // The scope is inside the if-block  var b = 1; // The scope is global  const c = 15; // The scope is inside the if-block    console.log(a);   // 4,   console.log(b);   // 1  console.log(c);   // 15} console.log(a);  // 5, the value changes to the initial console.log(b);  // 1, the value from if-block savesconsole.log(c);  // 11, the value changes to the initial
READ
Теперь аналитический раздел Яндекс.Маркета учитывает характеристики товара

И крайний код этого раздела:

JavaScript

1234a = 10; // it’s OK, the value of a is changed to 10b = 20; // it’s OK, the value of b is changed to 20c = 7; // SyntaxError: Identifier «c» has already beed declared const c = 15; // The same error

Что вышло? В блоке if мы объявили переменные «a» и «c» и изменили значение глобальной переменной «b». Вне блока «a» и «c» возвратились к своим исходным значениям. Опосля этого мы попробовали поменять значения всех переменных: let и var разрешают нам это созодать, а const возвращает ошибку. Причина в том, что const заявляет доступную лишь для чтения ссылку на значение в определенной области (оно быть может локальным либо глобальным). Вот почему нам удалось объявить новое значение переменной «c» в блоке if, но нам не удалось поменять значение вне его.

Неправильные ссылки на способы экземпляра

Давайте сделаем новейший объект и используем свойство prototype функции для прибавления способа «whoAmI». Потом сделайте экземпляр «obj» объекта (код ниже):

JavaScript

12345var MyObject = function() {}MyObject.prototype.whoAmI = function() {   console.log(this === window ? «window» : «MyObj»); }var obj = new MyObject();

Предварительный шаг завершился, давайте начнем созодать нашу жизнь проще: так как нам необходимо получить доступ к не так давно установленному способу, и мы желаем упростить его, давайте сделаем ссылку на него и проверим, работает ли она подабающим образом.

JavaScript

123obj.whoAmI(); // MyObjvar anotherMethod = obj.whoAmI;anotherMethod(); // window

И мы получаем выход «window» заместо ожидаемого «MyObj».

Почему? ОК, когда мы создаем ссылку varanotherMethod = obj.whoAmI, способ whoAmI определен в глобальной области видимости. Глобальная область — это объект окна в браузере, потому ключевое слово this становится равным окну, а не экземпляру MyObject . Если мы желаем сделать правильную ссылку на способ экземпляра, то нам необходимо вызвать этот способ из самого объекта либо создать ссылку на объект, а не только лишь на способ объекта.

Верная ссылка будет смотреться так:

JavaScript

123var obj = new MyObject(); var anotherObj = obj;anotherObj.whoAmI() // MyObj

либо же

JavaScript

12obj.link = obj.whoAmIobj.link(); // MyObj

И мы получаем верный итог.

Трудности использования this

JavaScript стал достаточно сложным языком. this – это ключевое слово JavaScript, значение которого оценивается во время выполнения зависимо от контекста.

JavaScript

12345678910function myFunction() {  var myObject = {     objProperty: «some text»,     objMethod: function() {        alert(objProperty);        }     }  myObject.objMethod();} myFunction();

И мы получаем «ReferenceError: objProperty is not defined». Функции, определенные для объекта JavaScript, обращаются к свойствам этого объекта JavaScript и не могут применять ссылочный идентификатор this. Верный код смотрится так (не this =)):

JavaScript

12345678910function myFunction() {  var myObject = {     objProperty: «some text»,     objMethod: function() {        alert(this.objProperty);        }     }  myObject.objMethod();}myFunction();

Мысль ординарна: когда вызывается объект myObject.objMethod , он становится myObject во время вызова объекта objMethod. Когда мы определяем объект и желаем получить доступ к его свойствам и способам, нам поначалу необходимо получить доступ к самому объекту (звучит разумно). Но есть и оборотные ситуации, когда this употребляется некорректно.

READ
Скрытие элементов в Веб

JavaScript

123456Game.prototype.restart = function () {  this.clearLocalStorage();  this.timer = setTimeout(function() {    this.clearBoard();   }, 0);}

Возвращает нам еще одну ошибку: «undefined is not a function». Дело в том, что this в строке this.clearBoard() является необязательным, поэтому что когда вы вызываете setTimeout(), вы работаете с window.setTimeout(), потому вы вызываете объект окна в браузере. Окно объекта не имеет способа clearBoard(). Верная форма будет смотреться так:

JavaScript

1234567Game.prototype.restart = function () {  var self = this;  this.clearLocalStorage();  this.timer = setTimeout(function() {    self.clearBoard(); // this = window  }, 0);}

И пример, который существует с момента выпуска EcmaScript2015:

JavaScript

123456Game.prototype.restart = function () {  this.clearLocalStorage();  this.timer = setTimeout(() => {    this.clearBoard(); // this = Game  }, 0);}

Это также сделалось вероятным опосля ECMAScript 6. Когда мы используем функцию стрелки, мы остаемся в области деяния предшествующей функции, не создавая новейшую локальную область.

Утечки памяти, и что с сиим соединено

Давайте начнем с кода:

JavaScript

123function myFunction() {  me = «You can’t touch me!»;}

Это модифицированный пример из 2-ой главы данной статьи, видите разницу?

Если да, это здорово — вы понимаете, как объявлять ненадобные глобальные переменные, и относитесь пристально, когда дело касается скорости кода. Неувязка с сиим кодом состоит в том, что когда мы вызываем функцию myFunction, мы создаем ненадобную глобальную переменную, которая прячется в фоновом режиме до того времени, пока код не закончится. Глобальная переменная создается поэтому, что мы присваиваем значение переменной, которая не была объявлена ранее.

Хотя переменные не занимают много памяти, очень много данных, хранящихся в кэше, замедляют скорость загрузки странички и негативно влияют на скорость браузера в целом. Есть несколько вероятных решений. Используйте локальные переменные:

JavaScript

123function myFunction() {  var me = «You can’t touch me!»;}

Используйте директиву «применять строго», которая не дозволяет вызывать необъявленную переменную:

JavaScript

1234function myFunction() {  “strict mode”  me = «You can’t touch me!»; //me is not defined}

Утечки памяти происходят, когда приложение хранит ненадобные данные, которые собиратель мусора не очищает во время работы. Другое событие, которое приводит к утечкам памяти, — это когда приложение употребляет память для выполнения определенной задачки: опосля выполнения задачки память освобождается, но время от времени это не так. Таковым образом, приложение хранит в памяти данные без предпосылки (потому что задачка выполнена).

Давайте разглядим иной код:

JavaScript

12345var trigger = document.getElementById(«trigger»);var elem = document.getElementById(‘elementToDelete’);trigger.addEventListener(«click», function() {  elem.remove();});

Когда мы исполняем код, elementToDelete удаляется из DOM. Но у нас все есть еще ссылка на него в прослушивателе, и в этот момент происходит утечка памяти, поэтому что выделенная память для объекта все еще употребляется. Решение последующее:

JavaScript

12345var trigger = document.getElementById(«trigger»);trigger.addEventListener(«click», function() {  var elem = document.getElementById(‘elementToDelete’);  elem.remove();});

Тут elem объявлена снутри прослушивателя. Таковым образом, когда мы удаляем ее, путь к объекту обрезается и память освобождается.

Создатель: Anastasia Ovchinnikova

Редакция: Команда webformyself.

Источник

Оценить статью
Блог о самом интересном.