Ако сте софтуерен инженер или студент по ИТ, може вече да работите с езика JavaScript, тъй като той се използва широко както при разработка от страна на клиента, така и от страна на сървъра. JavaScript е динамичен и лек език за компютърно програмиране. Първоначално той беше въведен като скриптов език за уеб разработка в началото на 90-те години от компанията Netscape. Както вече знаете, JavaScript е добре познат за разработването на уеб страници, докато “node.js” не беше представен през 2009 г. С помощта на “node.js” можем да използваме JavaScript извън уеб браузърите. В резултат на това той придоби огромна популярност сред back-end разработчиците и от няколко години JavaScript е признат за най-използвания език за програмиране в света.

ECMAScript

Въпреки че JavaScript е популярен език сред разработчиците, той имаше лоша репутация, защото не се развиваше правилно през последните години. Но с въвеждането на ECMAScript 6 (ES6), JavaScript получи някои големи промени и актуализации. И така, какво е този ECMAScript?

Акронимът ECMA означава Европейска асоциация на производителите на компютри. ECMAScript е спецификация за скриптови езици като JavaScript и ActionScript. ECMA публикува стандартни спецификации от време на време. Тези спецификации въвеждат нови функции в езика, което подобрява изживяването на разработчиците. Като пример версията на ES5, пусната с няколко нови метода за масиви, наречени „map()“, „reduce()“, „filter()“, заедно с функции за дата. Когато става въпрос за версия ES6, тя е известна като една от най-големите версии на ECMAScript досега. Той идва с функции като ключови думи let/const, класове, деструктуриране, обещания и т.н.

Забележка: JavaScript има свои собствени функции, които не са част от тези спецификации.

В следващата глава ще обясня някои основни промени, въведени в по-новите версии на ECMAScript.

Обхват на променливи

JavaScript има 3 типа ключови думи за деклариране на променливи, наречени като var, let,и const. Ключовите думи „let“ и „const“ бяха въведени с версията ES6. Тези две ключови думи предоставят променливи и константи Обхват на блока в JavaScript. Но преди ES6 JavaScript имаше само два типа обхвати, наречени Глобален обхват и Обхват на функцията. Нека видим пример, за да добием ясна представа.

Изход:

0
1
2
3
4
Value after iteration: 4

Както можете да видите в резултата, кодът работи без проблем. Но ако използвате ключовата дума “let”, за да декларирате променливата “num” вместо “var”, ще получите грешка на 6-ия ред. Причината за това е, че „let“ предоставя блоков обхват. Променливата, декларирана с помощта на ключовата дума „let“, може да бъде достъпна само в рамките на този конкретен кодов блок. В този случай в този for-цикъл.

За да предотвратим горния проблем, можем да декларираме променлива „num“ над обхвата на for-цикъла и след това да го използваме в него. Използването на ключови думи let/const е много полезно, когато трябва да напишете много дълъг скрипт, който съдържа много цикли и функции. Тъй като можете да декларирате променливи с едно и също име във всеки кодов блок, без да се сблъсквате с проблеми поради поведението на обхвата на блока.

Константи

От версията на ES6 можем да използваме ключовата дума „const“ в JavaScript, за да декларираме постоянна променлива. Както споменах в горния раздел, „const“ има същото поведение като ключовата дума „let“, но с една разлика. Това, защото постоянната променлива не може да бъде преназначена. Нека го видим с пример.

Както можете да видите в същността, декларирах 2 променливи, използвайки ключова дума „const“. Така че, ако стартирате първите 2 реда, това ще ви даде грешка, докато следващите 2 реда (4 и 5) работят без грешка. Причината за даването на грешка е очевидна, защото не можете да присвоите отново стойности за постоянна променлива.

Причината да не се даде никаква грешка в 5-ти ред, защото const защитава само променлива, която не е обект или масив. Така че дори да е постоянна, можете да промените стойността вътре в нея, но пак не можете да присвоите друга стойност.

Функции на стрелките

В JavaScript има няколко начина за дефиниране на функция, както е показано в следната същност.

Както можете да видите в същността, дефинирах 4 метода по 4 различни начина. Първата декларация на метод е обичайният начин за деклариране на метод в JS. Всички останали 3 метода са декларирани като „Функции със стрелки“, които бяха въведени в ES6. Тези функции със стрелки ни позволяват да напишем по-кратък синтаксис на функцията от обичайния начин. В случай, че смятате, че както обикновената, така и стрелковата функция се държат по един и същи начин, вижте следния пример.

Изход:

This is function1:  { function1: [Function: function1], function2: [Function: function2] }
This is function2:  {}

Както можете да видите в резултата, когато извикате „тази“ ключова дума в обикновена функция, тя представлява извикващия функцията (в този случай обект „obj“), докато функцията със стрелка игнорира „ тази” ключова дума.

Обработка на обекти

С по-новите версии на ECMAScript обектите получиха някои разумни промени. Така че, нека видим как можем да се справим с тях със следния пример.

Изход:

{
 name: 'Nisal',
 age: 25,
 printDetail: [Function: printDetail],
 salary: 100000,
 'project 99': 'Ready for the project'
}

„Служителят“ е стандартен обект, който има обичайна двойка ключ & стойност до функцията „printDetail()“. След това можете да видите ключ с име като „заплата“, но без стойност. Причината е, че ако дефинирате ключ по този начин, можете да вземете стойност от друг модул. Да приемем, че стойността на „заплата“ зависи от друг модул, така че можете да дефинирате променлива извън обекта и да й присвоите стойност. Тогава ключът „заплата“ ще бъде присвоен от тази стойност, както можете да видите на изхода.

След това можете да видите динамично свойство, наречено „статус“. Динамичното свойство е техника за използване на контейнер за ключ. Във втория ред на кода той присвоява ключ, наречен “project99” за това динамично свойство в този обект. Както можете да видите на изхода, той е заменен с този присвоен ключ. Това е наистина полезно, когато не знаете какъв ще бъде ключът по време на изпълнение.

Метод Object.freeze().

Както подсказва името, този метод се използва за замразяване на обект. Това означава, че ако използваме този метод за обект, вече не можем да променим този обект. Нека разберем това с пример.

Изход:

{ name: 'Nisal', contacts: { mobile: '071', home: '034' } }
{ name: 'Nisal', contacts: { mobile: '999', home: '034' } }

В горната същност създадох обект и добавих две свойства, наречени име и контакти. След това използвах метода ".freeze()" за този обект. След това се опитах да присвоя нова стойност за свойството „name“, но както показва изходът, това не се отразява поради използването на метода „.freeze()“.

Но в реда 13 се опитах да присвоя нова стойност за свойството „mobile“ на обект „contacts“ и тя беше присвоена, въпреки че използвах метода „.freeze()“. Причината за този резултат е, че ако използвате метода “.freeze()” за обект, той ще замрази само стойността от първо ниво на този обект. Това означава, че не засяга обекти от второ ниво (вътрешно ниво). Така че, ако ще използвате този метод, не забравяйте да отбележите тази точка.

Класове

Един JavaScript клас е основно план за създаване на обекти. Ако сте запознати с езиците Java или C#, може би вече знаете за класовете. Въпреки че не е съвсем същото, но все пак споделя някои прилики. Нека видим как можем да използваме класове в JavaScript със следния пример.

Изход:

The Camera is designed by Canon, and it's Rs:25000

Както можете да видите, има някои забележими разлики в класовете на JavaScript. JavaScript класът винаги има метод, наречен “constructor”и се извиква автоматично, когато се създава нов обект. Използва се за инициализиране на свойствата на обекта, както е показано в примера. Но методите трябва да се декларират извън „конструктора“.

Освен това използвах концепцията за наследяване в примера, като разширих класа „Камера“ с клас „DSLR“. Така че класът DSLR ще наследи всички свойства и методи от класа Camera. В конструктора на дъщерния клас (DSLR) трябва да извикате метода „super()“, за да предадете аргумента „марка“, който се изисква от родителския клас (Камера). Освен това можете лесно да замените методи, като използвате класове в JavaScript.

Деструктуриране

Деструктурирането беше въведено с версия ES6 и това е специален синтаксис, който ни позволява да разопаковаме масиви или обекти в куп променливи. Деструктурирането също е полезно, когато има сложни функции, които имат много параметри, стойности по подразбиране и т.н. Нека да видим как можем да използваме Destructuring в JS със следния пример.

Изход:

Nisal Pubudu
Nisal Pubudu
Full name: Nisal Pubudu

В горната същност създадох обект с име „студент“ и след това имам достъп до тези свойства по нормален начин. След това използвах синтаксис за деструктуриране на обекти, за да присвоя стойности на три променливи, използвайки стойностите от съответните им ключове на обекта ученик. Както можете да видите, и двата извеждат един и същ резултат, въпреки че деструктуриращият синтаксис е прост.

Също така можете да видите, че има функция, наречена „fullName()“, която трябва да отпечата пълното име на ученика. За тази функция се изискваха само полета „fName“ и „lName“. Така че в този случай нямам нужда от целия ученически обект. Затова използвах синтаксис за деструктуриране, за да постигна това, както е показано в примера.

Освен това можете да постигнете деструктурирането на масива, както е показано в следващия пример.

const animals = ["Lion", "Parrot", "Shark"];
//array destructuring
const [Mammal, Bird, Fish] = animals;
console.log(`${Mammal}, ${Fish}`); //Lion, Shark

Обещания

Обещанията са най-често срещаният начин за обработка на асинхронни операции в JavaScript. Преди обещанията разработчиците трябва да използват обратни извиквания, за да се справят с асинхронните операции. Следователно, те трябва да създадат множество обратни извиквания в рамките на обратните извиквания и в крайна сметка тази лоша практика получи жаргон; „Адът на обратното извикване.“ В резултат на това ES6 въведе Promises за лесно обработване на множество асинхронни операции.

Общото поведение на Promises в JavaScript е; когато дефинираме обещание в JS, то ще бъде разрешено, когато му дойде времето, или ще бъде отхвърлено. Това всъщност е цялата идея зад обещанията.

Има 3 състояния на обекта Promise.

  • Изпълнено: Показва, че обещаната операция е била успешна.
  • Отхвърлено:Показва, че обещаната операция е била неуспешна.
  • Предстоящо: Обещанието все още чака (все още не е изпълнено или отхвърлено).

Нека да видим как можем да използваме Promises в JS с прост пример.

Изход:

Promise is resolved successfully!!!

Както можете да видите в същността, създадох обещание, наречено „myPromise“ и то отнема два параметъра, един за успех (разрешаване) и един за неуспех (отхвърляне). Променливата „условие“ получава върнатата стойност на функцията „задача()“. За по-лесно обяснение функцията „task()“ винаги връща „true“ като стойност.

След това обещанието ще провери условието и ако е вярно, обещанието ще бъде разрешено, в противен случай ще бъде отхвърлено. Когато използваме Promise, методът „then()“ ще бъде извикан, след като Promise бъде разрешен. Тогава можем да решим какво да правим с разрешеното обещание. Но ако Promise се провали, тогава трябва да използваме метода „catch()“. В този сценарий той отговаря на условието на обещанието и в резултат обещанието ще бъде разрешено.

И така, това е краят на моята статия и се надявам да ви е харесала. Приятно кодиране👨‍💻.

Препратки