JavaScript Evolutsiyasi Qisqa Satrlarda! – DEV Community



Bismillah!

Taxminiy o’qish vaqti: ~9 daqiqa

Diskleymer: ba’zi atamalardan shundayligicha foydalanildi, tarjimasi ga’latiroq yoki notanish ko’rinmasligi uchun. Ba’zi iboralar esa ixchamroq ko’rinishga keltrildi, launch -> reliz.

Assalam alaykum! Bugun siz bilan JavaScript (JS) rivojlanish tarixiga biroz nazar tashlaymiz. Hozirgi kunda eng zamonaviy va eng ko’p qo’llaniladigan tillardan hisoblangan JS oldin qanday edi va o’tgan yillar ichida qanchalik o’zgardi va kimlar o’zgartirdi. Bu maqolada JSni boshlanish tarixiga to’xtalib o’tirilmadi, agar bu haqida to’liq bilishni xohlasangiz quyidagi maqoladan o’qib olsangiz bo’ladi: version history of javascript

Ko’p yillar davomida (< 2015 gacha) JS rivojlanishi (tilga yangi imkoniyatlarni qo’shib borish) juda sekin va salmoqsiz edi. Aniqroq gapiradigan bo’lsak, ECMAScript (JS ni spesifikatsiyasiga ma’sul normal) tilni 3.1 versiyasida 2009 dan beri qotib qolgan edi 🔒. Solishtirish uchun ushbu havolaga qaralsin. Keyinchalik bu versiya biz ko’proq tanish bo’lgan ECMAScript 5 yoki ES5 nomi bilan almashtirildi. Keyingi katta relizgacha JS group ancha uzoq kutib qoldi, deyarli 6 yil. Xatto ATM mashinalar ham tezroq yangilanib turiladi.

Bu vaqt mobaynida esa TC39 deb nomlangan JSni stardartlashtirish guruhi bir qancha OpenJS Foundation kabi ochiq jamiyatlar yordamida ECMAScript 2015 yoki ES6 versiyasini ishlab chiqishdi va 2015 yilga kelibgina taqdim etishdi. Bu JS tarixidagi shu paytgacha kirtilgan eng katta va muhim yangilanish edi.

Bu relizda JSga kiritilgan yangi imkoniyatlarning eng asosiylari bilan quyida tanishib chiqamiz. To’liq ma’lumotni esa ushbu havoladan ko’rib olsangiz bo’ladi.



Yangi Promise API

Promise obyekti muayyan asinxron operatsiya (serverga http so’rov) bilan ancha qulay tarzda ishlash imkonini beradi. Bu mexanizmdan oldin JSda asinxron kodlar callback lar yordamida amalga oshirilardi lekin noqulayliklari ko’p edi. Bunga yaqqol misol qilib callback hell 😩 keltirish mumkin. Buni quyidagi code-snippet da ko’rishingiz mumkin:

Demak Promiselar bizga quyidagilarni beradi:

  1. Yanada ekspressiv asinxron kod yozish.
  2. Yanada elegant error dealing with.

ekspressiv – qisqa satrlarda ko’p narsani namoyon eta olish.
elegant – nafis va yoqimli ko’rinish.

Qo’shimcha: ES7 async/await sintaksisi esa asinxron kodingni yanada qulaylashtirdi.



Class sintaksisi

Classlar JSning prototype mexanizmi ustiga qurilgan abstraksiyasidir. Javadagi classlar bilan adashtirilmasin chunki sintaktik bir xil ko’rinishda bo’lsada, ishlash mexamizmlari elementary darajada bir biridan farqlidir. JSda haqiqiy Prototypal Inheritance ni to’g’ri setup qilish biroz murakkabroq jarayon edi, classlar buni elegant holatga keltirdi.

// classlarsiz
perform Individual() {...}
Individual.prototype.getName = perform () {...}

perform Scholar() {}
Scholar.prototype.getScores = perform () {...}
Scholar.prototype = Object.create(Individual.prototype);
Scholar.prototype.constructor = Scholar;

// classlar bilan
class Individual {
  getName() {...}
}
class Scholar extends Individual {
  getScores() {...}
}
Enter fullscreen mode

Exit fullscreen mode

Lekin bu degani classlar yaxshiroq degani emas. Uni o’ziga yarasha kamchililari bor. Bu haqida esa boshqa maqolada bafurja muhokama qilamiz. Shaxsan males uchun classlar JSda obyektlar bilan ishlashga turli tumanlikni olib kirdi va Javaga o’xshash kompilyatorlik tillardan kelgan dasturchilarga visible qulaylik berdi ya’ni syntactic sugar.



Yagona modul tizimi

Har qanday dasturiy ta’minotda dastur kodining yaxshi strukturaviy qisimlarga ajratilgani, ham mantiqiy ham jismoniy, bu eng muhim masalalardan biridir. Bunga esa modullar orqali erishiladi. Afsuski, ES6 modul tizimidan oldingi modullash tizimlarida bir qator kamchiliklar mavjud edi, misol uchun server va shopper uchun common modul tizimining yo’qligi. Dastlabki modul tizimlaridan farqli o’laroq, yangi ECMAScript Modules (ESM) tizimi statik bog’liqliklardan foydalanish uchun JS sintaksisini yaxshiladi, bu esa 4 ta muhim afzalliklarni berdi:

  • Dastur kodining statik tahlili, o’lik kodni yo’q qilish (dead-code elimination) va keraksiz kodlarni topish (tree-shaking) kabi bir qancha zamonaviy dasturlash vositalarini ishini ancha samaraliroq qilishga imkon yaratdi.
  • Server va shopper uchun modul tizimini birlashtirdi, bu esa platformaga qarab turli xil modul tizimlarini talab qilish muammosini chiroyli hal etdi. (e.g. CommonJS va AMD)
  • butun dastur bo’ylab kodni qayta-qayta ishlata olishlik imkoniyatini yaxshiladi ya’ni extra elegant code sharing.
  • Kompilyatorlarning kodni tahlil qilish usulini optimallashtirdi.

Yashasin export/import yo’qolsin require/outline! (bu albatta xazil edi)



Arrow funksiyalar

Bu yangi standartdan oldin, JSda funksiyalarni yaratish uchun perform kalitso’zi ishlatilardi, endi esa funksiyalarni => maxsus arrow sintaksisi yordamida ekspressivroq tarzda e’lon qila olamiz. Arrow funksiyalar Pythondagi lambda funksiyalar kabidir va an’anaviy funksiyalardan bir qancha farqlari bor. Xususan, arrow funksiyalar an’anaviy funksiyalardagi this, arguments yoki tremendous kabi mexanizmlarga ega emas . Bundan tashqari, name, apply va bind kabi scopelarni o’zgartira olishda ishlatiladigan vositalar bilan ishlatila olinmaydi.

// ES6 dan oldin 
perform add(num1, num2) {
 return num1 + num2;
}

// ES6 dan keyin 
const addImplicit = (num1, num2) => num1 + num2;
Enter fullscreen mode

Exit fullscreen mode

Arrow funksiyalaridan foydalanishning eng katta qulayligi sifatida setTimeout() va EventTarget.addEventListener() kabi metodlar bilan oson ishlatilishini aytish mumkin, chunki ularda odatda funksiyaning tegishli scopeda bajarilishini taʼminlash uchun closure mexanizmini tadbiq qilinishi yoki bind va apply kabi metodlarni ishlatish talab etiladi.



Destrukturalash sintaksisi

Obyektni destrukturalash obyektning propertiylarini qulay tarzda ajratib olishga va ularni o’zgaruvchilarga osonroq o’zlashtirishga imkon yaratadi. Bu esa dastur kodidagi tartibsizliklarni (code litter) kamaytirishda samarali rol o’ynab kodni yanada ixcham va o’qishli ko’rinishga keltiradi.
Ko’rib o’zingiz baho bering:

const state = {
 identify: "Ahmad",
 age: 25,
 deal with: {
   zipCode: 7711,
   metropolis: "Tashkent"
 }
}

const { identify, deal with: { zipCode } } = state; // cool!
// solishtirish uchun
const zipCode = state.deal with.zipCode;
const identify = state.deal with.zipCode;
Enter fullscreen mode

Exit fullscreen mode



Meta programming

Proxy obyekti sizga dasturni ishlash jarayonida (runtime) meta levelda muayyan operatsiyalarni intersept qila olish va o’ziga qulay shaklga keltira olish imkoniyatlarini taqdim etadi.

intersept qilish – dasturning biron operatsiyasini bajarilish jarayoni orasiga suqulib kirib unga ta’sir o’tkazish, zimdan kuzatish yoki o’zgartira olishlik. (dasturni ishlash jarayoni bu RAMda aktiv ishchi holatda bo’lishlik degani)
meta stage – ya’ni runtime vaqtida dasturlash tilining elementary mexamizmlari ishlashiga aralasha olish yoki o’zgartira olish

Proxylar muayyan turdagi muammolarni hal qilishda juda foydali mexanizm hisoblanadi. Cross cutting aspects bunga yaqqol misol bo’la oladi. Actual misol sifatida esa Vue3 ning reaktiv tizimini keltirish mumkin, ular Proxylardan juda samarali foydalanishgan va oldingi versiyadagi hacky yechimni (Object.defineProperties()) Proxylar bilan almashtirishgan. Bu haqida boshqa maqolalarimizda batafsil to’xtalib o’tamiz.



Iterator va generatorlar

ES6 dagi menga eng yoqqan imkoniyatlardan biri

Bular tilning eng kam tilga olinadigan biroq eng ko’p ishlatiladigan imkoniyatlarini asosida yotuvchi mexanizmlardir (Promise, async/await, and so on). JSchilar uchun katta imkoniyatlarni ochib beradi. Bular alohida e’tiborga loyiq mazvular bo’lgani uchun ular haqida ham alohida publish yozish istagi bor. Hozircha esa quyidagi code-snippet lar bilan cheklanamiz:

// DOM traversal 
const dad or mum = doc.createElement("div");
dad or mum.innerHTML = `
  <div id="subTree">  
    <type>    
      <enter sort="textual content"/>  
    </type>  
    <p>Paragraph</p>
    <span>Span</span>
  </div>
`;
const subTree = dad or mum;

// recursive yechim
const traverseDOMRecursive = perform (elem, cb) {
  cb(elem);
  elem = elem.firstElementChild;
  whereas (elem) {
    traverseDOMRecursive(elem, cb);
    elem = elem.nextElementSibling;
  }
};
perform callback(aspect) {
  console.assert(aspect !== null, aspect.nodeName);
}
traverseDOMRecursive(subTree, callback);

// generatorlar bilan
const traverseDOMGenerator = perform* (elem) {
  yield elem;
  elem = elem.firstElementChild;
  whereas (elem) {
    yield* traverseDOMGenerator(elem);
    elem = elem.nextElementSibling;
  }
};
// for loop ni ichida ishlatilishiga e'tibor bering
for (let aspect of traverseDOMGenerator(subTree)) {
  console.log("aspect", aspect.nodeName);
}
Enter fullscreen mode

Exit fullscreen mode

Endi esa iteratorlarga misol:

class Vary {
  constructor(...args) 
  [Symbol.iterator]() {
    return this;
  }
  subsequent() {
    if (this.finish > this.begin) {
      const outcome = { performed: false, worth: this.begin };
      this.begin = this.begin + this.step;
      return outcome;
    } else return { performed: true, worth: undefined };
  }
}

perform vary(...args) {
  return new Vary(...args);
}

// ajoyib emasmi!
console.log([...range(4)]);
console.log([...range(2, 5)]);
console.log([...range(1, 10, 3)]);
Enter fullscreen mode

Exit fullscreen mode



Block scoped o’zgaruvchilar

ES6 tilga yangi o’zgaruvchilarni olib kirdi va ular var ni o’rnini deyarli to’liq egalladi. ES6 gacha, JSda faqatgina funksional va international scopelar bor edi, let va const qo’shilishi tufayli JSda endi block scope ham mavjud. var bilan e’lon qilingan o’zgaruvchilarda locality mexanizmi yo’q edi shuning uchun odatda international scope da e’lon qilingan boshqa o’zgaruvchilar bilan to’qnashuv bo’lishini oldini olish qiyin edi. Block scope esa bu muammoni hal qildi.

locality – biron o’zgaruvchining dastur kodining faqat o’ziga tegishli qismidagina {} mavjud bo’la olishi.

let x = 5;

perform blockExample() {
 let x = 2 // bu funksional scope
 if(x >= 3) {
   let x = 10; // bu block scope
   console.log(x, "if blokining ichida");
 } else {
   let x = 1;
   console.log(x, "else blokining ichida");
 }
 console.log(x, "funksiyani ichidagi");
}

blockExample();
console.log(x, "international x");
Enter fullscreen mode

Exit fullscreen mode

const o’z nomi bilan constanta ya’ni o’zgarmas qiymatni bildiradi va u bilan e’lon qilingan o’zgaruvchilarga yangi qiymat berishga urinilsa dastur xatolik qaytaradi.



Template literal

Stringlar bilan ishlash imkoniyatlarini yanada kengaytirdi. Qulay interpolyatsiya ${} sintaksini olib kirdi.

let identify = "Ahmad";
const HOLIDAY = "Iyd al-Fitr"; 
// ES6 dan oldin: 
console.log(identify + "ning sevimli bayrami bu " + HOLIDAY);
// ES6 dan keyin:
console.log(`${identify}ning sevimli bayrami bu ${HOLIDAY}`);
// yoki
const multiLineString = `Cross-cutting considerations are components 
of a program that depend on or should have an effect on many different 
components of the system`
Enter fullscreen mode

Exit fullscreen mode

Va hokazo!

Yana bir eng muhim yangilik bu: JS ni reliz sikli (tilga yangi imkoniyatlarni davomiy tarzda qo’shib borish davri) yillik ko’rinishga o’tkazildi.



Biroz TC39 haqida

Endi TC39 haqida bir-ikki luqma hole aytamiz. Bu ishchi guruh yetakchi internet kompaniyalar a’zolaridan tashkil topgan bo’lib asosiy maqsadi ECMAScriptni rivojlantirib borishdan iborat, bu esa o’z navbatida JSni standartlashtirib borish degani. Bundan tashqari TC39 JSchilar keng ommasiga tilga o’zlarining takliflarini (proposal) berish imkoniyatini bajaruvchi platforma sifatida ham faoliyat yuritadi. Bu takliflar ochiq shaklda butun dunyodagi webchilar ommasiga qo’yiladi va muayyan vaqt davomida belgilangan struktura bo’yicha bir nechta bosqichlarda muhokama qilinadi. Quyida bu haqida biroz to’xtalamiz.



TC39 bosqichlari

  • Stage 0 (strawman): Bu norasmiy bosqich bo’lib, taklif har qanday erkin shaklda bo’lishi mumkin, demak hamma ishtirok eta oladi. Taklifingizni kirgazish uchun esa TC39ning a’zosi bo’lishingiz yoki ECMA Internationalga registratsiya qilishingiz talab etiladi. Registratsiyadan so’ng taklifingizni esdiscuss mailing listi orqali bildirishingiz yoki boshqa takliflarni kuzatib borishingiz mumkin.

  • Stage 1 (proposal): Strawman dan so’ng, biron TC39 a’zosi sizning taklifingiz keyingi bosqichga o’tish uchun qo’llab-quvvatlashi kerak. Bu a’zo berilgan taklif nima uchun foydali ekanligini tushuntirishi va u amalga oshirilganda qanday ishlashi va ko’rinishini tasvirlashi kerak 🐥.

  • Stage 2 (draft): Bu bosqichda taklifning to’liq spesifikatsiyasi ishlab chiqiladi va eksperimental hisoblanadi (do it at your personal danger ☢️ ). Agar taklif bu bosqichga yetib kela olsa, odatda TC39 bu taklifni qachondir JSni spesifikatsiyasiga kiritilishini kutadi.

  • Stage 3 (candidate): Bu bosqichda berilgan taklif to’liq deb hisoblanadi va imzolanadi. Bu bosqichdan keyin taklifga o’zgartirishlar kiritish juda ham kam bo’lib, faqatgina juda kiritik muammolari topilsagina va ko’p muddatli foydalanishdan so’ngina amalga oshiriladi. Ushbu bosqichda taklifni qo’rqmasdan ishlatsangiz bo’ladi chunki ma’lum muddatdan so’ng, taklif xavfsiz tarzda so’nggi bosqichga o’tkaziladi.

  • Stage 4 (completed): Bu yakuniy bosqich hisoblanadi. Agar taklif bu bosqichgacha yetib kelsa uni endi bemalol formal tarzda ECMAScript standartining spesifikatsiyasiga qo’shildi desa bo’ladi 🏁.

Bunday sog’lom va dinamik usulda tilga yangi imkoniyatlarni kiritib borish juda ham muhim jarayon hisoblanadi. Buning natijasida JS bugungi dunyoning tez o’zgarib boruvchi va murakkab talablariga labbay deb javob bera oladi.
Quyida ushbu taklif (proposal) lardan ba’zilarini keltirib o’tamiz.

  • Private class fieldlari va nihoyat classlarda entry modifierlarni (non-public,static) qo’llash imkonini beruvchi sintaksis.
  • Observablelar streamlarga asoslangan reaktiv dasturlash paradigmasini olib kiradi JSga. Shaxsan menga eng yoqqan takliflardan biri. Bu haqida ham alohida maqola yozish niyat bor. RxJS (Angular) bilan ishlab ko’rganlar bo’lsa buni nimaligini juda yaxshi tushunishadi, endi bu library emas balki native 🚀 !!!
  • Pipeline operatori UNIXdagi pipe utilitasiga o’xshash asosan funksional tillarga tegishli bo’lgan mexanizmni JS fuksiyalarida ishlatish imkonini beradi.
  • Yangi bind operatori Operate.prototype.bind ni yanada elegant tarzda ishlatish imkonini beruvchi yangi sintaksis

Ushbu maqola Internetdan olingan ma’lumotlar yordamida tayyorlandi. Har qanday taklif va mulozalar bosh ustiga, ularni pastdagi sharhlar bo’limida qoldirishingiz mumkin. Maqsadimiz o’zbek tilida IT bilan bo’gliq sifatli contentni ko’paytirish va ularni hammaga qulay uslubda tarqatishdir. Bunda eng katta muammolarimizdan biri bu sohaga oid inglizcha atamalarni qanday qilib tushinarli tarzda, o’z ma’nosidan chiqib ketmagan holda qisqa va lo’nda shaklda yetkazishdir. Chunki to’g’ridan to’g’ri (direct) tarjima ko’p hollarda haddan tashqari uzun, tushunarsiz va o’zining dastlabki ma’nosidan chiqib ketgan shaklga kelib qolishidir. Shuning uchun sarbast (erkin) uslubni (postimizda boshida ham bu haqida biroz to’xtalgandik) sinab ko’rishga qaror qildik. Haligi aytishgandek: Better of each worlds 🙂 !

Add a Comment

Your email address will not be published. Required fields are marked *