diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..490051876 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: iliakan diff --git a/.gitignore b/.gitignore index 6f90fd190..1a71fb7c8 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ sftp-config.json Thumbs.db +/svgs \ No newline at end of file diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md index 59c52b1ff..e77cdc882 100644 --- a/1-js/01-getting-started/1-intro/article.md +++ b/1-js/01-getting-started/1-intro/article.md @@ -24,26 +24,44 @@ Brauzerlar o'z JavaScript interpretatorlariga ega, ular gohida "JavaScript virtu Har bir intetptretatorni o'z nomi mavjud. Masalan: +<<<<<<< HEAD - [V8]() -- Chrome va Opera brauzerlarida qo'llanadi. - [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- Firefox brauzerida. - Explorer brauzerining turli xil versiyalari uchun "Trident" va "Chakra", Microsoft Edge uchun "ChakraCore", Safari uchun "Nitro" va "SquirrelFish" va boshqalar kabi boshqa kod nomlari mavjud. Yuqoridagi atamalarni eslab qolish yaxshi, chunki ular netdagi ishlab chiquvchilar maqolalarida qo'llaniladi. Biz ulardan ham foydalanamiz. Masalan, agar "X funktsiyasini V8 qo'llab-quvvatlasa", ehtimol u Chrome va Opera-da ishlaydi. +======= +- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome, Opera and Edge. +- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox. +- ...There are other codenames like "Chakra" for IE, "JavaScriptCore", "Nitro" and "SquirrelFish" for Safari, etc. + +The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome, Opera and Edge. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="Intetptretatorlar ishni qanday bajarishadi?" Intetptretatorlar murakkab. Ammo asoslari oson. +<<<<<<< HEAD 1. Intetptretator (agar u brauzer bo'lsa, avtomatik o'rnatilgan) skriptni o'qiydi ("tahlil qiladi"). 2. Keyin u skriptni mashina tiliga o'zgartiradi ("kompilyatsiya qiladi"). 3. Va keyin mashina kodi juda tez ishlaydi. +======= +1. The engine (embedded if it's a browser) reads ("parses") the script. +2. Then it converts ("compiles") the script to machine code. +3. And then the machine code runs, pretty fast. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Interpretatatsiya jarayonning har bir bosqichida optimallashtirishlarni qo'llaydi. U hattoki kompilyatsiya qilingan skriptni ishlayotganda kuzatib boradi, u orqali oqib o'tadigan ma'lumotlarni tahlil qiladi va shu bilimga asoslangan holda mashina kodiga optimallashtirishlarni qo'llaydi. Tugatgandan so'ng, skriptlar juda tez ishlaydi. ``` ## Brauzerdagi JavaScript nimani bajara oladi? +<<<<<<< HEAD Zamonaviy JavaScript - bu "xavfsiz" dasturlash tili. Bu xotira yoki protsessorga(CPU) past darajadagi kirishni ta'minlamaydi, chunki dastlab uni talab qilmaydigan brauzerlar uchun yaratilgan. +======= +Modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or the CPU, because it was initially created for browsers which do not require it. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 JavaScript-ning imkoniyatlari u ishlayotgan muhitga juda bog'liq. Masalan, [Node.js](https://wikipedia.org/wiki/Node.js) JavaScript-ga o'zboshimchalik bilan fayllarni o'qish / yozish, tarmoq so'rovlarini bajarish va hk. @@ -59,7 +77,11 @@ Masalan: ## JavaScript-da brauzerda nima qila olmaysiz? +<<<<<<< HEAD JavaScript-ning brauzerdagi imkoniyatlari foydalanuvchi xavfsizligi uchun cheklangan. Maqsad yomon veb-sahifaning shaxsiy ma'lumotlarga kirishini yoki foydalanuvchi ma'lumotlariga zarar etkazishini oldini olishdir. +======= +JavaScript's abilities in the browser are limited to protect the user's safety. The aim is to prevent an evil webpage from accessing private information or harming the user's data. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bunday cheklovlarga quyidagilar kiradi: @@ -67,6 +89,7 @@ Bunday cheklovlarga quyidagilar kiradi: Zamonaviy brauzerlar unga fayllar bilan ishlashga imkon beradi, lekin kirish cheklangan va faqat foydalanuvchi brauzer oynasiga faylni "tushirish" yoki uni `` yorlig'i orqali tanlash kabi ba'zi bir amallarni bajargan taqdirdagina taqdim etiladi. +<<<<<<< HEAD Kamera/mikrofon va boshqa qurilmalar bilan o'zaro aloqa qilish usullari mavjud, ammo ular foydalanuvchidan aniq ruxsat talab qiladi. Shunday qilib, JavaScript-ni qo'llab-quvvatlaydigan sahifa veb-kamerani yashirincha yoqmasligi, atrofni kuzatishi va ma'lumotni [NSA](https://en.wikipedia.org/wiki/National_Security_Agency) ga yuborishi mumkin emas. - Turli xil yorliqlar/oynalar odatda bir-birlarini bilishmaydi. Ba'zan ular bilishadi, masalan, bitta oyna ikkinchisini ochish uchun JavaScript-ni ishlatganda. Ammo bu holatda ham bitta sahifadagi JavaScript-ni boshqa saytlarga kirish mumkin emas, agar ular turli saytlardan (boshqa domendan, protokoldan yoki portdan) bo'lsa. @@ -80,20 +103,44 @@ Bunday cheklovlarga quyidagilar kiradi: ![](limitations.svg) Agar JavaScript brauzerdan tashqarida, masalan serverda ishlatilsa, bunday cheklovlar mavjud emas. Zamonaviy brauzerlar kengaytirilgan ruxsat so'rashi mumkin bo'lgan plagin / kengaytmalarga ham imkon beradi. +======= + There are ways to interact with the camera/microphone and other devices, but they require a user's explicit permission. So a JavaScript-enabled page may not sneakily enable a web-camera, observe the surroundings and send the information to the [NSA](https://en.wikipedia.org/wiki/National_Security_Agency). +- Different tabs/windows generally do not know about each other. Sometimes they do, for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other page if they come from different sites (from a different domain, protocol or port). + + This is called the "Same Origin Policy". To work around that, *both pages* must agree for data exchange and must contain special JavaScript code that handles it. We'll cover that in the tutorial. + + This limitation is, again, for the user's safety. A page from `http://anysite.com` which a user has opened must not be able to access another browser tab with the URL `http://gmail.com`, for example, and steal information from there. +- JavaScript can easily communicate over the net to the server where the current page came from. But its ability to receive data from other sites/domains is crippled. Though possible, it requires explicit agreement (expressed in HTTP headers) from the remote side. Once again, that's a safety limitation. + +![](limitations.svg) + +Such limitations do not exist if JavaScript is used outside of the browser, for example on a server. Modern browsers also allow plugins/extensions which may ask for extended permissions. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## JavaScript-ni qaysi xususiyatlari uni noyob qiladi? JavaScript hech bo'lmaganda _uchta_ ajoyib xususiyatga ega: +<<<<<<< HEAD ```solishtiring + HTML va CSS bilan to'liq integratsiyasi. + Oson ishlar osongina amalga oshiriladi. + Barcha asosiy brauzerlar tomonidan qo'llab-quvvatlanadi va ularda standart sifatida yoqilgan. +======= +```compare ++ Full integration with HTML/CSS. ++ Simple things are done simply. ++ Supported by all major browsers and enabled by default. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` JavaScript - bu uchta narsani birlashtirgan yagona brauzer texnologiyasidir. +<<<<<<< HEAD Bu JavaScript-ni noyob qiladi. Shuning uchun u brauzer feyslarini yaratishda eng keng tarqalgan vositadir. +======= +That said, JavaScript can be used to create servers, mobile applications, etc. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Yangi texnologiyani o'rganishni rejalashtirayotib, uning istiqbollarini tekshirish ham muhimdir. Keling, zamonaviy tendentsiyalarga o'taylik. @@ -101,22 +148,43 @@ Yangi texnologiyani o'rganishni rejalashtirayotib, uning istiqbollarini tekshiri JavaScript-ning sintaksisi hammaning ehtiyojlariga mos kelmaydi. Turli odamlar turli xususiyatlarni xohlashadi. +<<<<<<< HEAD Bu kutilgan hodisa bo'lishi kerak edi, chunki loyihalar va talablar har bir kishi uchun farq qiladi. +======= +So, recently a plethora of new languages appeared, which are *transpiled* (converted) to JavaScript before they run in the browser. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shunday qilib, yaqinda juda ko'p yangi tillar paydo bo'ldi va brauzer ularni ishlatishdan oldin JavaScript-ga aylantirib bajaradi. Zamonaviy asboblar transpilatsiyani juda tez va shaffof bajaradi, aslida dasturchilar kodni bitta tilda yozganda, ular uni avtomatik tarzda boshqa tilga aylantirish imkonini beradi. +<<<<<<< HEAD Bunday tillarning namunalari: - [CoffeeScript](http://coffeescript.org/) JavaScript uchun "sintaktik shakar" dir. Ushbu til bizga qisqa sintaksisni va aniqroq kodni taqdim etadi. Odatda, Ruby dasurchilari shu tilni afzal ko'rishadi. - [TypeScript](http://www.typescriptlang.org/) murakkab tizimlarni ishlab chiqish, soddalashtirish va qo'llab-quvvatlash uchun "strict data typing"ni qo'shishga qaratilgan. Microsoft tomonidan ishlab chiqilgan. - [Dart](https://www.dartlang.org/) brauzer bo'lmagan muhitda (mobil ilovalar kabi) ishlaydigan o'z dvigateliga ega bo'lgan mustaqil til. Bu dastlab JavaScript uchun zaxira sifatida Google tomonidan taklif etildi, lekin hozirgi paytda, brauzerlar shu tilni ham JS-ga transpilatsiya bo'lishini talab qilishadi. +======= +- [CoffeeScript](https://coffeescript.org/) is "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it. +- [TypeScript](https://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft. +- [Flow](https://flow.org/) also adds data typing, but in a different way. Developed by Facebook. +- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google. +- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript. +- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node. + +There are more. Of course, even if we use one of these transpiled languages, we should also know JavaScript to really understand what we're doing. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bundan ham ko'proq tillar mavjud. Albatta, biz bu tillardan birini ishlatsak ham, biz nima qilayotganimizni tushunish uchun JavaScript-ni bilishimiz kerak. +<<<<<<< HEAD ## Xulosa - JavaScript dastlab brauzer tili sifatida yaratilgan, ammo hozirgi paytda ko'pgina boshqa muhitlarda ham qo'llanilmoqda. - Bugun JavaScript HTML/CSS bilan to'la integratsiyalashgan va eng keng tarqalgan brauzer tili hisoblanadi. - JavaScript-ga "aylanadigan" va muayyan xususiyatlarni taqdim etadigan ko'plab tillar mavjud. Javascriptni o'zlashtirgandan so'ng kamida qisqacha ularga bir nazar tashlash tavsiya etiladi. +======= +- JavaScript was initially created as a browser-only language, but it is now used in many other environments as well. +- Today, JavaScript has a unique position as the most widely-adopted browser language, fully integrated with HTML/CSS. +- There are many languages that get "transpiled" to JavaScript and provide certain features. It is recommended to take a look at them, at least briefly, after mastering JavaScript. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/01-getting-started/2-manuals-specifications/article.md b/1-js/01-getting-started/2-manuals-specifications/article.md index 76ede7e4c..3257813a0 100644 --- a/1-js/01-getting-started/2-manuals-specifications/article.md +++ b/1-js/01-getting-started/2-manuals-specifications/article.md @@ -2,7 +2,11 @@ Bu kitob *qo'llanma*dir. U sizga tilni bosqichma-bosqich o'rganishda yordam berish maqsadida yozilgan. Ammo asoslar bilan tanishgandan so'ng, sizga boshqa manbalar kerak bo'ladi. +<<<<<<< HEAD ## Xususiyat +======= +This book is a *tutorial*. It aims to help you gradually learn the language. But once you're familiar with the basics, you'll need other resources. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 [ECMA-262 xususiyatsi](https://www.ecma-international.org/publications/standards/Ecma-262.htm) JavaScript haqida eng chuqur, batafsil va rasmiy ma'lumotlarni o'z ichiga oladi. U tilni belgilaydi. @@ -10,7 +14,11 @@ Ammo shunchalik rasmiy bo'lganligi sababli, dastlab tushunish qiyin. Shuning uch Har yili yangi xususiyat versiyasi chiqariladi. Bu nashrlar orasida eng so'nggi xususiyat loyihasi da joylashgan. +<<<<<<< HEAD "Deyarli standart" deb ataladigan ("3-bosqich") xususiyatlarni o'z ichiga olgan yangi ilg'or xususiyatlar haqida o'qish uchun dagi takliflarni ko'ring. +======= +A new specification version is released every year. Between these releases, the latest specification draft is at . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shuningdek, agar siz brauzer uchun ishlab chiqayotgan bo'lsangiz, qo'llanmaning [ikkinchi qismida](info:browser-environment) yoritilgan boshqa xususiyatlar ham mavjud. @@ -20,9 +28,15 @@ Shuningdek, agar siz brauzer uchun ishlab chiqayotgan bo'lsangiz, qo'llanmaning Uni da topishingiz mumkin. +<<<<<<< HEAD Garchi ko'pincha internet qidiruvidan foydalanish yaxshiroqdir. So'rovda "MDN [atama]" dan foydalaning, masalan `parseInt` funksiyasini qidirish uchun . ## Moslik jadvallari +======= + You can find it at . + +Although, it's often best to use an internet search instead. Just use "MDN [term]" in the query, e.g. to search for the `parseInt` function. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 JavaScript rivojlanayotgan til, yangi xususiyatlar muntazam ravishda qo'shiladi. @@ -31,6 +45,15 @@ Brauzer va boshqa dvigatellar orasidagi qo'llab-quvvatlashni ko'rish uchun: - - xususiyat bo'yicha qo'llab-quvvatlash jadvallari, masalan zamonaviy kriptografiya funksiyalarini qaysi dvigatellar qo'llab-quvvatlashini ko'rish uchun: . - - til xususiyatlari va ularni qo'llab-quvvatlovchi yoki qo'llab-quvvatlamaydigan dvigatellar jadvali. +<<<<<<< HEAD Bu manbalarning barchasi real hayotdagi ishlab chiqishda foydali, chunki ular til tafsilotlari, ularning qo'llab-quvvatlanishi va hokazo haqida qimmatli ma'lumotlarni o'z ichiga oladi. Muayyan xususiyat haqida chuqur ma'lumotga ehtiyoj sezganingizda, ularni (yoki ushbu sahifani) eslab qoling. +======= +- - per-feature tables of support, e.g. to see which engines support modern cryptography functions: . +- - a table with language features and engines that support those or don't support. + +All these resources are useful in real-life development, as they contain valuable information about language details, their support, etc. + +Please remember them (or this page) for the cases when you need in-depth information about a particular feature. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/01-getting-started/3-code-editors/article.md b/1-js/01-getting-started/3-code-editors/article.md index 90d2b551a..c67d1039a 100644 --- a/1-js/01-getting-started/3-code-editors/article.md +++ b/1-js/01-getting-started/3-code-editors/article.md @@ -12,8 +12,13 @@ IDE loyihani yuklaydi (bu juda ko'p fayl bo'lishi mumkin), fayllar o'rtasida nav Agar siz IDE ni tanlamagan bo'lsangiz, quyidagi variantlarni ko'rib chiqing: +<<<<<<< HEAD - [Visual Studio Code](https://code.visualstudio.com/) (o'zaro faoliyatli platforma, bepul). - [WebStorm](http://www.jetbrains.com/webstorm/) (o'zaro faoliyatli platforma, pullik). +======= +- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free). +- [WebStorm](https://www.jetbrains.com/webstorm/) (cross-platform, paid). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Windows uchun "Visual Studio" ham mavjud, "Visual Studio Code" bilan aralashmaslik kerak. "Visual Studio" - bu pullik va qudratli Windows muharriri .NET platformasi uchun juda mos keladi. Bundan tashqari, JavaScript-da yaxshi. Bepul versiyasi ham mavjud [Visual Studio Community](https://www.visualstudio.com/vs/community/). @@ -29,12 +34,20 @@ Ular asosan faylni bir zumda ochish va tahrirlash uchun ishlatiladi. Amalda yengil muharrirlarda juda ko'p plaginlar bo'lishi mumkin, shu jumladan direktoriya-darajasidagi sintaksis analizatorlari va avtokompleterlar, shuning uchun engil muharrir va IDE o'rtasida qat'iy chegara yo'q. +<<<<<<< HEAD Quyidagi variantlar sizning e'tiboringizga loyiqdir: - [Atom](https://atom.io/) (o'zaro faoliyatli platforma, bepul). - [Sublime Text](http://www.sublimetext.com) (o'zaro faoliyatli platforma, shartli ravishda bepul). - [Notepad++](https://notepad-plus-plus.org/) (Windows, bepul). - [Vim](http://www.vim.org/) va [Emacs](https://www.gnu.org/software/emacs/) ham zo'r agar ularni qanday foydalanishni bilsangiz. +======= +There are many options, for instance: + +- [Sublime Text](https://www.sublimetext.com/) (cross-platform, shareware). +- [Notepad++](https://notepad-plus-plus.org/) (Windows, free). +- [Vim](https://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool if you know how to use them. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Tortishmaylik @@ -42,4 +55,13 @@ Yuqoridagi ro'yxatlardagi muharrirlarni men yoki men yaxshi dasturchi deb hisobl Bizning katta dunyoda boshqa yaxshi kod muharrirlari ham bor. Iltimos, o'zingizga eng yoqqanini tanlang. +<<<<<<< HEAD Kod muharririni tanlash, boshqa har qanday vosita kabi, individual va loyihalar, odatlar, va shaxsiy xohishlarga bog'liq. +======= +The choice of an editor, like any other tool, is individual and depends on your projects, habits, and personal preferences. + +The author's personal opinion: + +- I'd use [Visual Studio Code](https://code.visualstudio.com/) if I develop mostly frontend. +- Otherwise, if it's mostly another language/platform and partially frontend, then consider other editors, such as XCode (Mac), Visual Studio (Windows) or Jetbrains family (Webstorm, PHPStorm, RubyMine etc, depending on the language). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md index 320452e77..e8639ced0 100644 --- a/1-js/01-getting-started/4-devtools/article.md +++ b/1-js/01-getting-started/4-devtools/article.md @@ -22,7 +22,7 @@ Dasturchilar uchun vositalar standart ravishda Console yorlig'ida ochiladi. Bu shunday ko'rinadi: -![chrome](chrome.png) +![chrome](chrome.webp) Dasturchilar vositalarining aniq ko'rinishi sizning Chrome versiyangizga bog'liq. U vaqti-vaqti bilan o'zgarib turadi, ammo shunga o'xshash bo'lishi kerak. @@ -49,7 +49,11 @@ Ularning tashqi ko'rinishi va hissi o'xshash. Ushbu vositalardan birini qanday i Safari (Windows/Linux tomonidan qo'llab-quvvatlanmaydigan Mac brauzeri) bu yerda biroz o'ziga xosdir. Avval "Dasturchi menyusini" yoqishimiz kerak. +<<<<<<< HEAD Preferences ni oching va "Advanced" oynasiga o'ting. Pastki qismida belgilash katakchasi mavjud: +======= +Open Settings and go to the "Advanced" pane. There's a checkbox at the bottom: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ![safari](safari.png) diff --git a/1-js/01-getting-started/4-devtools/chrome.png b/1-js/01-getting-started/4-devtools/chrome.png deleted file mode 100644 index 4cb3ea2f4..000000000 Binary files a/1-js/01-getting-started/4-devtools/chrome.png and /dev/null differ diff --git a/1-js/01-getting-started/4-devtools/chrome.webp b/1-js/01-getting-started/4-devtools/chrome.webp new file mode 100644 index 000000000..bdf067079 Binary files /dev/null and b/1-js/01-getting-started/4-devtools/chrome.webp differ diff --git a/1-js/01-getting-started/4-devtools/chrome@2.webp b/1-js/01-getting-started/4-devtools/chrome@2.webp new file mode 100644 index 000000000..2aeca5898 Binary files /dev/null and b/1-js/01-getting-started/4-devtools/chrome@2.webp differ diff --git a/1-js/01-getting-started/4-devtools/chrome@2x.png b/1-js/01-getting-started/4-devtools/chrome@2x.png deleted file mode 100644 index b87404a8f..000000000 Binary files a/1-js/01-getting-started/4-devtools/chrome@2x.png and /dev/null differ diff --git a/1-js/01-getting-started/4-devtools/safari.png b/1-js/01-getting-started/4-devtools/safari.png index 64c7a3f6c..4538827eb 100644 Binary files a/1-js/01-getting-started/4-devtools/safari.png and b/1-js/01-getting-started/4-devtools/safari.png differ diff --git a/1-js/01-getting-started/4-devtools/safari@2x.png b/1-js/01-getting-started/4-devtools/safari@2x.png index 27def4d09..1561b2bd9 100644 Binary files a/1-js/01-getting-started/4-devtools/safari@2x.png and b/1-js/01-getting-started/4-devtools/safari@2x.png differ diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md index 7f1ca70ca..4f0749f21 100644 --- a/1-js/02-first-steps/01-hello-world/article.md +++ b/1-js/02-first-steps/01-hello-world/article.md @@ -66,7 +66,11 @@ Skript fayllari HTML-ga `src` atributi bilan biriktiriladi: ``` +<<<<<<< HEAD Bu yerda `/path/to/script.js` - skript fayliga (sayt ildizidan) mutlaq yo'l. +======= +Here, `/path/to/script.js` is an absolute path to the script from the site root. One can also provide a relative path from the current page. For instance, `src="script.js"`, just like `src="./script.js"`, would mean a file `"script.js"` in the current folder. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Joriy sahifadan nisbiy yo'lni ham ko'rsatish mumkin. Masalan, `src="script.js"` joriy papkada joylashgan `"script.js"` faylini bildiradi. diff --git a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md index f28a645fa..21558ef46 100644 --- a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md +++ b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md @@ -12,13 +12,24 @@ const birthday = '18.04.1982'; // tug'ilgan kun const age = someCode(birthday); // yosh ``` +<<<<<<< HEAD Bu erda bizda doimiy `birthday` sanasi mavjud va `age` ba'zi kodlar yordamida `birthday` dan hisoblab chiqilgan (bu qisqartirish uchun ko'rsatilmagan, chunki bu erda tafsilotlar muhim emas). +======= +Here we have a constant `birthday` for the date, and also the `age` constant. + +The `age` is calculated from `birthday` using `someCode()`, which means a function call that we didn't explain yet (we will soon!), but the details don't matter here, the point is that `age` is calculated somehow based on the `birthday`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `birthday` uchun katta registridan foydalanish to'g'ri bo'ladimi? `age` uchun chi? Yoki ikkalsigayam foydalanish to'g'rimi? ```js +<<<<<<< HEAD const BIRTHDAY = '18.04.1982'; // katta registridan foydalanish kerakmi? const AGE = someCode(BIRTHDAY); // katta registridan foydalanish kerakmi? -``` +======= +const BIRTHDAY = '18.04.1982'; // make birthday uppercase? +const AGE = someCode(BIRTHDAY); // make age uppercase? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 +``` diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index 40be6c918..62c0f6eff 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -24,7 +24,11 @@ Endi biz unga tayinlash operatori `=` yordamida ma'lumot kiritishimiz mumkin: let message; *!* +<<<<<<< HEAD message = 'Hello'; // 'Hello' stringini message nomli o'zgaruvchiga saqlash +======= +message = 'Hello'; // store the string 'Hello' in the variable named message +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 */!* ``` @@ -63,7 +67,11 @@ let age = 25; let message = 'Hello'; ``` +<<<<<<< HEAD Ba'zi odamlar ko'p satrli uslubda bir nechta o'zgaruvchilarni aniqlaydi: +======= +Some people also define multiple variables in this multiline style: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js no-beautify let user = 'John', @@ -88,16 +96,26 @@ Eski skriptlarda siz boshqa kalit so'zni ham topishingiz mumkin: `let` o'rniga ` *!*var*/!* message = 'Hello'; ``` +<<<<<<< HEAD `var` kalit so'zi `let` bilan *deyarli* bir xil. U ham o'zgaruvchini e'lon qiladi, ammo biroz boshqacha, "eski maktab" usulida. `let` va `var` orasida nozik farqlar bor, ammo ular bizga hali muhim emas. Biz ularni bobida batafsil ko'rib chiqamiz. +======= +The `var` keyword is *almost* the same as `let`. It also declares a variable but in a slightly different, "old-school" way. + +There are subtle differences between `let` and `var`, but they do not matter to us yet. We'll cover them in detail in the chapter . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```` ## Hayotiy o'xshashlik Agar uni ma'lumotlar uchun "quti" sifatida tasavvur qilsak, unda noyob nomlangan stiker yopishtirilgan bo'lsa, "o'zgaruvchi" tushunchasini osongina tushunishimiz mumkin. +<<<<<<< HEAD Masalan, `message` o'zgaruvchisini ichida `"Hello!"` qiymati bo'lgan `"message"` yorlig'i bilan qutiga o'xshatish mumkin: +======= +For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ![](variable.svg) @@ -105,6 +123,11 @@ Biz qutiga istalgan qiymatni qo'yishimiz mumkin. Shuningdek, uni xohlagancha marta o'zgartirishimiz mumkin: +<<<<<<< HEAD +======= +We can also change it as many times as we want: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let message; @@ -150,12 +173,21 @@ let message = "That"; // SyntaxError: 'message' has already been declared Demak, biz o'zgaruvchini bir marta e'lon qilishimizdan keyin unga `let` ishlatmasdan murojaat qilishimiz kerak. ```` +<<<<<<< HEAD ```smart header="Funksional tillar" Qiziq tomoni shundaki, [sof funksional](https://en.wikipedia.org/wiki/Purely_functional_programming) dasturlash tillari mavjud, masalan [Haskell](https://en.wikipedia.org/wiki/Haskell), ular o'zgaruvchi qiymatlarini o'zgartirishni taqiqlaydi. +======= +```smart header="Functional languages" +It's interesting to note that there exist so-called [pure functional](https://en.wikipedia.org/wiki/Purely_functional_programming) programming languages, such as [Haskell](https://en.wikipedia.org/wiki/Haskell), that forbid changing variable values. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bunday tillarda qiymat "qutiga" saqlangandan so'ng, u abadiy u yerda qoladi. Agar biz boshqa narsani saqlashimiz kerak bo'lsa, til bizni yangi quti yaratishga (yangi o'zgaruvchi e'lon qilishga) majbur qiladi. Eskisini qayta ishlatib bo'lmaydi. +<<<<<<< HEAD Dastlabki qarashda biroz g'alati tuyulishi mumkin bo'lsa-da, bu tillar jiddiy ishlanmaga juda qodir. Bundan tashqari, parallel hisoblashlar kabi sohalar mavjud bo'lib, bu cheklov ma'lum afzalliklarni beradi. +======= +Though it may seem a little odd at first sight, these languages are quite capable of serious development. More than that, there are areas like parallel computations where this limitation confers certain benefits. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## O'zgaruvchilarni nomlash [#variable-naming] @@ -193,19 +225,32 @@ let 1a; // raqam bilan boshlanishi mumkin emas let my-name; // defislar '-' nomda ruxsat etilmagan ``` +<<<<<<< HEAD ```smart header="Katta-kichik harflar muhim" `apple` va `APPLE` nomli o'zgaruvchilar ikki xil o'zgaruvchidir. ``` ````smart header="Lotin bo'lmagan harflarga ruxsat berilgan, ammo tavsiya etilmaydi" Kirill harflari, xitoy logogrammalar va hokazo har qanday tildan foydalanish mumkin: +======= +```smart header="Case matters" +Variables named `apple` and `APPLE` are two different variables. +``` + +````smart header="Non-Latin letters are allowed, but not recommended" +It is possible to use any language, including Cyrillic letters, Chinese logograms and so on, like this: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let имя = '...'; let 我 = '...'; ``` +<<<<<<< HEAD Texnik jihatdan bu yerda xato yo'q. Bunday nomlar ruxsat etilgan, ammo o'zgaruvchi nomlarida ingliz tilidan foydalanish xalqaro konventsiya hisoblanadi. Kichik skript yozsak ham, uning oldida uzoq hayot bo'lishi mumkin. Boshqa mamlakatlardan odamlar uni o'qishlari kerak bo'lishi mumkin. +======= +Technically, there is no error here. Such names are allowed, but there is an international convention to use English in variable names. Even if we're writing a small script, it may have a long life ahead. People from other countries may need to read it sometime. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```` ````warn header="Zaxiralangan nomlar" @@ -260,13 +305,21 @@ const myBirthday = '18.04.1982'; myBirthday = '01.01.2001'; // xato, konstantani qayta tayinlab bo'lmaydi! ``` +<<<<<<< HEAD Dasturchi o'zgaruvchi hech qachon o'zgarmasligiga ishonchi komil bo'lsa, bu faktni kafolatlash va hammaga etkazish uchun uni `const` bilan e'lon qilishi mumkin. ### Bosh harfli konstantalar +======= +When a programmer is sure that a variable will never change, they can declare it with `const` to guarantee and communicate that fact to everyone. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bajarilishdan oldin ma'lum bo'lgan, eslab qolish qiyin bo'lgan qiymatlar uchun takma nom sifatida konstantalardan foydalanish keng tarqalgan amaliyot. +<<<<<<< HEAD Bunday konstantalar bosh harflar va pastki chiziqlar yordamida nomlanadi. +======= +There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, "veb" (o'n oltilik) formatda ranglar uchun konstantalar yarataylik: @@ -289,17 +342,30 @@ Foydalar: Konstanta uchun qachon bosh harflardan foydalanishimiz va qachon oddiy nomlashimiz kerak? Keling, buni aniqlashtiriruylik. +<<<<<<< HEAD "Konstanta" bo'lish shunchaki o'zgaruvchining qiymati hech qachon o'zgarmasligini anglatadi. Ammo ba'zi konstantalar bajarilishdan oldin ma'lum (qizil uchun o'n oltilik qiymat kabi) va ba'zi konstantalar ish vaqtida, bajarilish davomida *hisoblanadi*, lekin boshlang'ich tayinlashdan keyin o'zgarmaydi. Masalan: +======= +Being a "constant" just means that a variable's value never changes. But some constants are known before execution (like a hexadecimal value for red) and some constants are *calculated* in run-time, during the execution, but do not change after their initial assignment. + +For instance: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js const pageLoadTime = /* veb-sahifa yuklanish vaqti */; ``` +<<<<<<< HEAD `pageLoadTime` ning qiymati sahifa yuklanishidan oldin ma'lum emas, shuning uchun u oddiy nomlanadi. Ammo bu hali ham konstanta, chunki tayinlashdan keyin o'zgarmaydi. Boshqacha qilib aytganda, bosh harfli konstantalar faqat "qattiq kodlangan" qiymatlar uchun takma nom sifatida ishlatiladi. +======= +The value of `pageLoadTime` is not known before the page load, so it's named normally. But it's still a constant because it doesn't change after the assignment. + +In other words, capital-named constants are only used as aliases for "hard-coded" values. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Narsalarni to'g'ri nomlash @@ -307,18 +373,31 @@ O'zgaruvchilar haqida gapirganda, yana bir juda muhim narsa bor. O'zgaruvchi nomi toza, aniq ma'noga ega bo'lishi va u saqlaydigan ma'lumotlarni tasvirlashi kerak. +<<<<<<< HEAD O'zgaruvchilarni nomlash dasturlashtirining eng muhim va murakkab ko'nikmalaridan biridir. O'zgaruvchi nomlariga bir qarash yangi boshlovchi yoki tajribali dasturchi tomonidan yozilgan kodni aniqlash mumkin. Haqiqiy loyihada vaqtning ko'p qismi noldan butunlay alohida narsa yozishdan ko'ra mavjud kod bazasini o'zgartirish va kengaytirishga sarflanadi. Bir muddat boshqa ish bilan shug'ullanganimizdan keyin qandaydir kodga qaytsak, yaxshi belgilangan ma'lumotni topish ancha oson. Boshqacha qilib aytganda, o'zgaruvchilarning yaxshi nomlari bo'lganda. +======= +Variable naming is one of the most important and complex skills in programming. A glance at variable names can reveal which code was written by a beginner versus an experienced developer. + +In a real project, most of the time is spent modifying and extending an existing code base rather than writing something completely separate from scratch. When we return to some code after doing something else for a while, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 O'zgaruvchini e'lon qilishdan oldin uning to'g'ri nomi haqida o'ylashga vaqt ajrating. Buni qilish sizga katta foyda keltiradi. Bajarilishi kerak bo'lgan qoidalar: +<<<<<<< HEAD - `userName` yoki `shoppingCart` kabi inson o'qiy oladigan nomlardan foydalaning. - Nima qilayotganingizni bilmasangiz, `a`, `b` va `c` kabi qisqartmalar yoki qisqa nomlardan qoching. - Nomlarni maksimal darajada tavsiflovchi va qisqa qiling. Yomon nomlar misollari `data` va `value`. Bunday nomlar hech narsa demaydi. Ularni faqat kod konteksti o'zgaruvchi qaysi ma'lumot yoki qiymatga ishora qilayotganini juda aniq qilsa ishlatish mumkin. - Jamoangizdagi va fikringizdagi atamalar bo'yicha kelishing. Agar sayt tashrif buyuruvchisi "user" deb atalsa, biz tegishli o'zgaruvchilarni `currentVisitor` yoki `newManInTown` o'rniga `currentUser` yoki `newUser` deb nomlashimiz kerak. +======= +- Use human-readable names like `userName` or `shoppingCart`. +- Stay away from abbreviations or short names like `a`, `b`, and `c`, unless you know what you're doing. +- Make names maximally descriptive and concise. Examples of bad names are `data` and `value`. Such names say nothing. It's only okay to use them if the context of the code makes it exceptionally obvious which data or value the variable is referencing. +- Agree on terms within your team and in your mind. If a site visitor is called a "user" then we should name related variables `currentUser` or `newUser` instead of `currentVisitor` or `newManInTown`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Oddiy eshitiladimi? Haqiqatan ham shunday, ammo amalda tavsiflovchi va qisqa o'zgaruvchi nomlari yaratish unchalik oson emas. Harakat qiling. diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md index 6c4e8d202..ede963b62 100644 --- a/1-js/02-first-steps/05-types/article.md +++ b/1-js/02-first-steps/05-types/article.md @@ -47,7 +47,11 @@ Oddiy sonlardan tashqari, ushbu ma'lumot turiga tegishli "maxsus raqamli qiymatl alert( "not a number" / 2 ); // NaN, bunday bo'lish xato ``` +<<<<<<< HEAD `NaN` yopishqoq. `NaN` ustidagi har qanday keyingi matematik amal `NaN` ni qaytaradi: +======= + `NaN` is sticky. Any further mathematical operation on `NaN` returns `NaN`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert( NaN + 1 ); // NaN @@ -55,7 +59,11 @@ Oddiy sonlardan tashqari, ushbu ma'lumot turiga tegishli "maxsus raqamli qiymatl alert( "not a number" / 2 - 1 ); // NaN ``` +<<<<<<< HEAD Demak, agar matematik ifodaning biror joyida `NaN` bo'lsa, u butun natijaga tarqaladi (bunga faqat bitta istisno bor: `NaN ** 0` bu `1`). +======= + So, if there's a `NaN` somewhere in a mathematical expression, it propagates to the whole result (there's only one exception to that: `NaN ** 0` is `1`). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="Matematik amallar xavfsiz" JavaScript da matematik amallar "xavfsiz". Biz hamma narsani qilishimiz mumkin: nolga bo'lish, raqamli bo'lmagan stringlarni raqam sifatida qarash va hokazo. @@ -69,9 +77,26 @@ Raqamlar bilan ishlash haqida ko'proq ma'lumotni bobida ko'ramiz. ## BigInt [#bigint-type] +<<<<<<< HEAD JavaScript da "number" turi (253-1) dan kattaroq (`9007199254740991`) yoki manfiylar uchun -(253-1) dan kichikroq butun qiymatlarni xavfsiz ifodalay olmaydi. Aniq qilib aytganda, "number" turi kattaroq butun sonlarni saqlashi mumkin (1.7976931348623157 * 10308 gacha), ammo xavfsiz butun sonlar diapazoni ±(253-1) dan tashqarida aniqlik xatosi bo'ladi, chunki barcha raqamlar belgilangan 64-bitli xotiraga sig'maydi. Shuning uchun "taxminiy" qiymat saqlanishi mumkin. +======= +In JavaScript, the "number" type cannot safely represent integer values larger than (253-1) (that's `9007199254740991`), or less than -(253-1) for negatives. + +To be really precise, the "number" type can store larger integers (up to 1.7976931348623157 * 10308), but outside of the safe integer range ±(253-1) there'll be a precision error, because not all digits fit into the fixed 64-bit storage. So an "approximate" value may be stored. + +For example, these two numbers (right above the safe range) are the same: + +```js +console.log(9007199254740991 + 1); // 9007199254740992 +console.log(9007199254740991 + 2); // 9007199254740992 +``` + +So to say, all odd integers greater than (253-1) can't be stored at all in the "number" type. + +For most purposes ±(253-1) range is quite enough, but sometimes we need the entire range of really big integers, e.g. for cryptography or microsecond-precision timestamps. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, bu ikki raqam (xavfsiz diapazondan yuqorida) bir xil: @@ -95,9 +120,15 @@ const bigInt = 1234567890123456789012345678901234567890n; `BigInt` sonlari kamdan-kam kerak bo'lganligi sababli, biz ularni bu yerda ko'rib chiqmaymiz, balki ularga alohida bob ajratdik. Bunday katta sonlar kerak bo'lganda uni o'qing. +<<<<<<< HEAD ## String (satr) JavaScript da string qo'shtirnoqlar bilan o'ralgan bo'lishi kerak. +======= +## String + +A string in JavaScript must be surrounded by quotes. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let str = "Hello"; @@ -219,9 +250,15 @@ Shunday muhim bo'lganligi sababli, obyektlar maxsus munosabatga loyiq. Primitiv ## typeof operatori [#type-typeof] +<<<<<<< HEAD `typeof` operatori operandning turini qaytaradi. Turli turdagi qiymatlarni turlicha qayta ishlashni xohlaganda yoki shunchaki tezkor tekshirish qilishni xohlaganda foydali. `typeof x` ga murojaat string ko'rinishida tur nomini qaytaradi: +======= +The `typeof` operator returns the type of the operand. It's useful when we want to process values of different types differently or just want to do a quick check. + +A call to `typeof x` returns a string with the type name: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js typeof undefined // "undefined" @@ -251,21 +288,58 @@ typeof alert // "function" (3) Oxirgi uchta satr qo'shimcha tushuntirish talab qilishi mumkin: +<<<<<<< HEAD 1. `Math` matematik amallarni ta'minlovchi o'rnatilgan obyekt. Biz uni bobida o'rganamiz. Bu yerda u shunchaki obyekt misoli sifatida xizmat qiladi. 2. `typeof null` ning natijasi `"object"`. Bu JavaScript ning eng dastlabki kunlaridan kelib chiqqan va muvofiqlik uchun saqlangan `typeof` dagi rasman tan olingan xato. Albatta, `null` obyekt emas. Bu o'zining alohida turiga ega maxsus qiymat. `typeof` ning xatti-harakati bu yerda noto'g'ri. 3. `typeof alert` ning natijasi `"function"`, chunki `alert` funksiya. Biz funksiyalarni keyingi boblarda o'rganamiz, u yerda JavaScript da maxsus "function" turi yo'qligini ham ko'ramiz. Funksiyalar obyekt turiga tegishli. Ammo `typeof` ularni boshqacha ko'rib, `"function"` qaytaradi. Bu ham JavaScript ning eski kunlaridan kelib chiqqan. Texnik jihatdan bunday xatti-harakat to'g'ri emas, ammo amalda qulay bo'lishi mumkin. ```smart header="`typeof(x)` sintaksisi" Siz boshqa sintaksisga ham duch kelishingiz mumkin: `typeof(x)`. Bu `typeof x` bilan bir xil. +======= +1. `Math` is a built-in object that provides mathematical operations. We will learn it in the chapter . Here, it serves just as an example of an object. +2. The result of `typeof null` is `"object"`. That's an officially recognized error in `typeof`, coming from very early days of JavaScript and kept for compatibility. Definitely, `null` is not an object. It is a special value with a separate type of its own. The behavior of `typeof` is wrong here. +3. The result of `typeof alert` is `"function"`, because `alert` is a function. We'll study functions in the next chapters where we'll also see that there's no special "function" type in JavaScript. Functions belong to the object type. But `typeof` treats them differently, returning `"function"`. That also comes from the early days of JavaScript. Technically, such behavior isn't correct, but can be convenient in practice. + +```smart header="The `typeof(x)` syntax" +You may also come across another syntax: `typeof(x)`. It's the same as `typeof x`. + +To put it clear: `typeof` is an operator, not a function. The parentheses here aren't a part of `typeof`. It's the kind of parentheses used for mathematical grouping. + +Usually, such parentheses contain a mathematical expression, such as `(2 + 2)`, but here they contain only one argument `(x)`. Syntactically, they allow to avoid a space between the `typeof` operator and its argument, and some people like it. + +Some people prefer `typeof(x)`, although the `typeof x` syntax is much more common. +``` + +## Summary +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Aniq qilib aytganda: `typeof` operator, funksiya emas. Bu yerdagi qavslar `typeof` ning bir qismi emas. Bu matematik guruhlash uchun ishlatiladigan qavslar turi. +<<<<<<< HEAD Odatda, bunday qavslar `(2 + 2)` kabi matematik ifodani o'z ichiga oladi, ammo bu yerda ular faqat bitta argument `(x)` ni o'z ichiga oladi. Sintaktik jihatdan ular `typeof` operatori va uning argumenti orasidagi bo'shliqdan qochishga imkon beradi va ba'zi odamlar buni yoqtiradi. +======= +- Seven primitive data types: + - `number` for numbers of any kind: integer or floating-point, integers are limited by ±(253-1). + - `bigint` for integer numbers of arbitrary length. + - `string` for strings. A string may have zero or more characters, there's no separate single-character type. + - `boolean` for `true`/`false`. + - `null` for unknown values -- a standalone type that has a single value `null`. + - `undefined` for unassigned values -- a standalone type that has a single value `undefined`. + - `symbol` for unique identifiers. +- And one non-primitive data type: + - `object` for more complex data structures. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ba'zi odamlar `typeof(x)` ni afzal ko'radi, garchi `typeof x` sintaksisi ancha keng tarqalgan. ``` +<<<<<<< HEAD ## Xulosa +======= +- Usually used as `typeof x`, but `typeof(x)` is also possible. +- Returns a string with the name of the type, like `"string"`. +- For `null` returns `"object"` -- this is an error in the language, it's not actually an object. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 JavaScript da 8 ta asosiy ma'lumot turi mavjud. diff --git a/1-js/02-first-steps/07-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md index b77c991f5..2245362da 100644 --- a/1-js/02-first-steps/07-type-conversions/article.md +++ b/1-js/02-first-steps/07-type-conversions/article.md @@ -6,8 +6,13 @@ Masalan, `alert` har qanday qiymatni ko'rsatish uchun avtomatik ravishda stringg Shuningdek, qiymatni kutilayotgan turga aniq o'zgartirishimiz kerak bo'lgan holatlar ham bor. +<<<<<<< HEAD ```smart header="Obyektlar haqida hali gapirmayapmiz" Ushbu bobda biz obyektlarni ko'rib chiqmaymiz. Hozircha biz faqat primitiv turlar haqida gaplashamiz. +======= +```smart header="Not talking about objects yet" +In this chapter, we won't cover objects. For now, we'll just be talking about primitives. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Keyinchalik, obyektlar haqida o'rganganimizdan so'ng, bobida obyektlar qanday mos kelishini ko'ramiz. ``` @@ -34,7 +39,11 @@ String o'zgartirish asosan aniq. `false` `"false"` ga aylanadi, `null` `"null"` ## Raqamli o'zgartirish +<<<<<<< HEAD Raqamli o'zgartirish matematik funktsiyalar va ifodalarda avtomatik ravishda sodir bo'ladi. +======= +Numeric conversion in mathematical functions and expressions happens automatically. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, bo'lish `/` raqam bo'lmagan qiymatlarga qo'llanilganda: @@ -69,8 +78,13 @@ Raqamli o'zgartirish qoidalari: |-------|-------------| |`undefined`|`NaN`| |`null`|`0`| +<<<<<<< HEAD |true va false | `1` va `0` | | `string` | Boshi va oxiridagi bo'shliqlar (bo'shliqlar, tab `\t`, yangi satrlar `\n` va hokazo) olib tashlanadi. Agar qolgan string bo'sh bo'lsa, natija `0` bo'ladi. Aks holda, stringdan raqam "o'qiladi". Xato `NaN` beradi. | +======= +|true and false | `1` and `0` | +| `string` | Whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. | +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Misollar: @@ -130,7 +144,11 @@ O'zgartirish qoidalarga amal qiladi: |`undefined`|`NaN`| |`null`|`0`| |true / false | `1 / 0` | +<<<<<<< HEAD | `string` | String "aynan shunday" o'qiladi, ikkala tarafdagi bo'shliqlar (bo'shliqlar, tab `\t`, yangi satrlar `\n` va hokazo) e'tiborga olinmaydi. Bo'sh string `0` ga aylanadi. Xato `NaN` beradi. | +======= +| `string` | The string is read "as is", whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. | +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 **`Boolean o'zgartirish`** -- Mantiqiy amallarda sodir bo'ladi. `Boolean(value)` bilan bajarilishi mumkin. diff --git a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md index 619769a23..027fb7842 100644 --- a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md +++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md @@ -17,6 +17,7 @@ undefined + 1 = NaN // (6) " \t \n" - 2 = -2 // (7) ``` +<<<<<<< HEAD ## Tushuntirishlar 1. String bilan qo'shish `"" + 1` `1` ni stringga o'zgartiradi: `"" + 1 = "1"`, va keyin bizda `"1" + 0` bo'ladi, xuddi shu qoida qo'llaniladi. @@ -31,4 +32,13 @@ undefined + 1 = NaN // (6) 6. `undefined` raqamli o'zgartirishdan keyin `NaN` ga aylanadi. -7. String raqamga o'zgartirilganda string boshi va oxiridagi bo'shliq belgilari olib tashlanadi. Bu yerda butun string `\t`, `\n` va ularning orasidagi "oddiy" bo'shliq kabi bo'shliq belgilaridan iborat. Shuning uchun, bo'sh stringga o'xshab, u `0` ga aylanadi. \ No newline at end of file +7. String raqamga o'zgartirilganda string boshi va oxiridagi bo'shliq belgilari olib tashlanadi. Bu yerda butun string `\t`, `\n` va ularning orasidagi "oddiy" bo'shliq kabi bo'shliq belgilaridan iborat. Shuning uchun, bo'sh stringga o'xshab, u `0` ga aylanadi. +======= +1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied. +2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`. +3. The addition with a string appends the number `5` to the string. +4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it). +5. `null` becomes `0` after the numeric conversion. +6. `undefined` becomes `NaN` after the numeric conversion. +7. Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md index 3d95b5c04..0d2f4b634 100644 --- a/1-js/02-first-steps/08-operators/article.md +++ b/1-js/02-first-steps/08-operators/article.md @@ -52,9 +52,15 @@ Qoldiq operatori `%`, ko'rinishiga qaramay, foizlar bilan bog'liq emas. Masalan: ```js run +<<<<<<< HEAD alert(5 % 2); // 1, 5 ni 2 ga bo'lishdan qoldiq alert(8 % 3); // 2, 8 ni 3 ga bo'lishdan qoldiq alert(8 % 4); // 0, 8 ni 4 ga bo'lishdan qoldiq +======= +alert( 5 % 2 ); // 1, the remainder of 5 divided by 2 +alert( 8 % 3 ); // 2, the remainder of 8 divided by 3 +alert( 8 % 4 ); // 0, the remainder of 8 divided by 4 +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ### Daraja \*\* @@ -71,7 +77,11 @@ alert(2 ** 3); // 2³ = 8 alert(2 ** 4); // 2⁴ = 16 ``` +<<<<<<< HEAD Matematikadagi kabi, daraja operatori butun bo'lmagan sonlar uchun ham aniqlangan. +======= +Just like in maths, the exponentiation operator is defined for non-integer numbers as well. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, kvadrat ildiz ½ darajaga ko'tarishdir: @@ -84,7 +94,11 @@ alert(8 ** (1 / 3)); // 2 (1/3 daraja kub ildiz bilan bir xil) Keling, maktab arifmetikasidan tashqari JavaScript operatorlarining xususiyatlari bilan tanishaylik. +<<<<<<< HEAD Odatda, plyus operatori `+` raqamlarni qo'shadi. +======= +Let's meet the features of JavaScript operators that are beyond school arithmetics. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ammo, agar binary `+` stringlarga qo'llanilsa, u ularni birlashtiradi (konkatenatsiya): @@ -194,6 +208,7 @@ JavaScript da ko'plab operatorlar mavjud. Har bir operator tegishli ustunlik raq Mana [ustunlik jadvalidan](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) ko'chirma (buni eslab qolish shart emas, lekin unary operatorlar tegishli binary operatorlardan yuqoriroq ekanligini unutmang): +<<<<<<< HEAD | Ustunlik | Nomi | Belgi | | -------- | ------------ | ----- | | ... | ... | ... | @@ -209,10 +224,31 @@ Mana [ustunlik jadvalidan](https://developer.mozilla.org/en-US/docs/Web/JavaScri | ... | ... | ... | Ko'rib turganimizdek, "unary plyus" `14` ustunlikka ega, bu "qo'shish" (binary plyus)ning `11` ustunligidan yuqori. Shuning uchun `"+apples + +oranges"` ifodasida unary plyuslar qo'shishdan oldin ishlaydi. +======= +| Precedence | Name | Sign | +|------------|------|------| +| ... | ... | ... | +| 14 | unary plus | `+` | +| 14 | unary negation | `-` | +| 13 | exponentiation | `**` | +| 12 | multiplication | `*` | +| 12 | division | `/` | +| 11 | addition | `+` | +| 11 | subtraction | `-` | +| ... | ... | ... | +| 2 | assignment | `=` | +| ... | ... | ... | + +As we can see, the "unary plus" has a priority of `14` which is higher than the `11` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Tayinlash +<<<<<<< HEAD Shuni ta'kidlash kerakki, tayinlash `=` ham operator. U ustunlik jadvalida juda past `2` ustunlik bilan ro'yxatga olingan. +======= +Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shuning uchun biz o'zgaruvchini tayinlaganimizda, masalan `x = 2 * 2 + 1`, avval hisob-kitoblar bajariladi va keyin `=` baholanib, natijani `x` ga saqlaydi. @@ -307,9 +343,15 @@ Bunday operatorlar oddiy tayinlash bilan bir xil ustunlikka ega, shuning uchun u ```js run let n = 2; +<<<<<<< HEAD n *= 3 + 5; // o'ng qism birinchi baholanadi, n *= 8 bilan bir xil alert(n); // 16 +======= +n *= 3 + 5; // right part evaluated first, same as n *= 8 + +alert( n ); // 16 +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Oshirish/kamaytirish @@ -442,7 +484,11 @@ Operatorlar ro'yxati: - RIGHT SHIFT ( `>>` ) - ZERO-FILL RIGHT SHIFT ( `>>>` ) +<<<<<<< HEAD Bu operatorlar juda kamdan-kam ishlatiladi, eng past (bitli) darajada raqamlar bilan urishga to'g'ri kelganda. Biz bu operatorlarga tez orada muhtoj bo'lmaymiz, chunki veb-ishlanmada ular kam qo'llaniladi, lekin kriptografiya kabi ba'zi maxsus sohalarda foydali. Ehtiyoj tug'ilganda MDN dagi [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) bobini o'qishingiz mumkin. +======= +These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) chapter on MDN when a need arises. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Vergul diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md index d6d1583b0..b2b1acf72 100644 --- a/1-js/02-first-steps/09-comparison/article.md +++ b/1-js/02-first-steps/09-comparison/article.md @@ -4,10 +4,17 @@ Biz ko'plab taqqoslash operatorlarini matematikadan bilamiz. JavaScript da ular quyidagicha yoziladi: +<<<<<<< HEAD - Katta/kichik: a > b, a < b. - Katta/kichik yoki teng: a >= b, a <= b. - Teng: `a == b`, iltimos, qo'sh tenglik belgisi `==` tenglik testini anglatishini unutmang, bitta `a = b` esa tayinlashni anglatadi. - Teng emas: Matematikada belgilanishi , lekin JavaScript da a != b deb yoziladi. +======= +- Greater/less than: a > b, a < b. +- Greater/less than or equals: a >= b, a <= b. +- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment. +- Not equals: In maths the notation is , but in JavaScript it's written as a != b. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ushbu maqolada biz turli xil taqqoslashlar, JavaScript ularni qanday amalga oshirishi, shu jumladan muhim o'ziga xosliklar haqida ko'proq bilib olamiz. diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md index 5e8d426c2..f6c8ee719 100644 --- a/1-js/02-first-steps/10-ifelse/article.md +++ b/1-js/02-first-steps/10-ifelse/article.md @@ -68,9 +68,13 @@ if (cond) { ## "Else" ifodasi +<<<<<<< HEAD `If` ifodasi ixtiyoriy `else` blokini o'z ichiga olishi mumkin. U shart noto'g'ri bo'lganida amalga oshiriladi. Masalan: +======= +The `if` statement may contain an optional `else` block. It executes when the condition is falsy. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let year = prompt( @@ -214,10 +218,17 @@ alert(message); Avvaliga nima bo'layotganini tushunish qiyin bo'lishi mumkin. Ammo yaqindan ko'rib chiqqach, bu oddiy testlar ketma-ketligi ekanligini ko'rishimiz mumkin: +<<<<<<< HEAD 1. Birinchi savol belgisi `age < 3` ni tekshiradi. 2. Agar rost bo'lsa -- u qaytadi `'Salom bolakay!'`. Aks holda, u yo'g'on ichakdan '":"' keyingi ifodaga davom etadi, `age < 18` ni tekshirishadi. 3. Agar shu rost bo'lsa -- u qaytadi `'Salom!'`. Aks holda, u yo'g'on ichakdan '":"' keyingi ifodaga davom etadi, `age < 100` ni tekshirishadi. 4. Agar shu rost bo'lsa -- u qaytadi `'Assalomu aleykum!'`. Aks holda, u yo'g'on ichakdan '":"' ohirgi ifodaga davom etadi, `Qanday g'ayrioddiy yosh!` ni qaytaradi. +======= +1. The first question mark checks whether `age < 3`. +2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon ":", checking `age < 18`. +3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon ":", checking `age < 100`. +4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon ":", returning `'What an unusual age!'`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu `if..else` yordamida qanday ko'rinishga ega: diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index 325923626..effa4cc44 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -124,7 +124,11 @@ Bu "sof, klassik, faqat-boolean YOKI" bilan solishtirganda qiziqarli foydalanish Bu shuni anglatadiki, `||` o'z argumentlarini birinchi haqiqiy qiymatga yetguncha qayta ishlaydi, keyin qiymat darhol qaytariladi, boshqa argumentga tegmasdan turib. +<<<<<<< HEAD Bu xususiyatning ahamiyati, agar operand oddiy qiymat emas, balki o'zgaruvchi tayinlash yoki funksiya chaqiruvi kabi yon ta'sirli ifoda bo'lsa yaqqol ko'rinadi. +======= + The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Quyidagi misolda faqat ikkinchi xabar chop etiladi: diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md index c4e557ac9..b99db2388 100644 --- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md +++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md @@ -4,7 +4,11 @@ Nullab birlashtirish operatori ikki savol belgisi `??` bilan yoziladi. +<<<<<<< HEAD U `null` va `undefined` ni bir xil darajada ko'rib chiqadi, shuning uchun bu maqolada maxsus atama ishlatamiz. Agar ifoda `null` ham, `undefined` ham bo'lmasa, uni "aniqlangan" deb ataymiz. +======= +As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. For brevity, we'll say that a value is "defined" when it's neither `null` nor `undefined`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `a ?? b` ning natijasi: @@ -23,14 +27,24 @@ result = a !== null && a !== undefined ? a : b; Endi `??` nima qilishi mutlaqo aniq bo'lishi kerak. Qayerda yordam berishini ko'rib chiqaylik. +<<<<<<< HEAD `??` ning umumiy foydalanish holati - potensial aniqlanmagan o'zgaruvchi uchun standart qiymat berish. Masalan, bu yerda agar aniqlangan bo'lsa `user` ni, aks holda `Anonymous` ni ko'rsatamiz: +======= +The common use case for `??` is to provide a default value. + +For example, here we show `user` if its value isn't `null/undefined`, otherwise `Anonymous`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let user; +<<<<<<< HEAD alert(user ?? "Anonymous"); // Anonymous (user aniqlanmagan) +======= +alert(user ?? "Anonymous"); // Anonymous (user is undefined) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` Bu yerda `user` ga nom tayinlangan misol: @@ -38,14 +52,24 @@ Bu yerda `user` ga nom tayinlangan misol: ```js run let user = "John"; +<<<<<<< HEAD alert(user ?? "Anonymous"); // John (user aniqlangan) +======= +alert(user ?? "Anonymous"); // John (user is not null/undefined) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` Shuningdek, `null/undefined` bo'lmagan ro'yxatdan birinchi qiymatni tanlash uchun `??` ketma-ketligini ishlatishimiz mumkin. +<<<<<<< HEAD Aytaylik, bizda foydalanuvchi ma'lumotlari `firstName`, `lastName` yoki `nickName` o'zgaruvchilarida bor. Agar foydalanuvchi qiymat kiritmaslikni hal qilgan bo'lsa, ularning barchasi aniqlanmagan bo'lishi mumkin. Biz ushbu o'zgaruvchilardan birini ishlatib foydalanuvchi nomini ko'rsatmoqchimiz yoki agar ularning barchasi aniqlanmagan bo'lsa "Anonymous" ko'rsatmoqchimiz. +======= +Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to fill in the corresponding values. + +We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are `null/undefined`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Buning uchun `??` operatoridan foydalanamiz: @@ -77,7 +101,11 @@ alert(firstName || lastName || nickName || "Anonymous"); // Supercoder */!* ``` +<<<<<<< HEAD Tarixan YOKI `||` operatori birinchi bo'lib paydo bo'lgan. U JavaScript boshidanoq mavjud, shuning uchun dasturchilar uzoq vaqt davomida bunday maqsadlar uchun foydalanib kelishgan. +======= +Historically, the OR `||` operator was there first. It's been there since the beginning of JavaScript, so developers were using it for such purposes for a long time. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Boshqa tomondan, nullab birlashtirish operatori `??` JavaScript-ga yaqinda qo'shilgan va buning sababi odamlar `||` dan butunlay mamnun emas edi. @@ -108,11 +136,19 @@ Amalda nol balandlik ko'pincha to'g'ri qiymat bo'lib, standart bilan almashtiril ## Ustunlik +<<<<<<< HEAD `??` operatorining ustunligi `||` bilan deyarli bir xil, faqat biroz pastroq. [MDN jadvalida](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table) u `5` ga teng, `||` esa `6`. +======= +The precedence of the `??` operator is the same as `||`. They both equal `3` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu shuni anglatadiki, `||` kabi, nullab birlashtirish operatori `??` ham `=` va `?` dan oldin, lekin `+`, `*` kabi boshqa ko'pchilik operatsiyalardan keyin baholanadi. +<<<<<<< HEAD Shuning uchun agar biz boshqa operatorlar bilan ifodada `??` bilan qiymat tanlashni istasak, qavs qo'shishni ko'rib chiqing: +======= +So we may need to add parentheses in expressions like this: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let height = null; @@ -130,8 +166,13 @@ Aks holda, agar qavslarni tashlab qo'ysak, `*` ning ustunligi `??` dan yuqori bo // qavslarsiz let area = height ?? 100 * width ?? 50; +<<<<<<< HEAD // ...xuddi shu narsani bajaradi (ehtimol biz istagan narsa emas): let area = height ?? 100 * width ?? 50; +======= +// ...works this way (not what we want): +let area = height ?? (100 * width) ?? 50; +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ### ?? ni && yoki || bilan ishlatish diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md index 2de57b015..8bcea8ae8 100644 --- a/1-js/02-first-steps/13-while-for/article.md +++ b/1-js/02-first-steps/13-while-for/article.md @@ -6,8 +6,25 @@ Masalan, ro'yxatdan tovarlarni birin-ketin chiqarish yoki 1 dan 10 gacha bo'lgan _Tsikllar_ - bir xil kodni bir necha marta takrorlash usuli. +<<<<<<< HEAD ```smart header="for..of va for..in tsikllari" Ilg'or o'quvchilar uchun kichik e'lon. +======= +```smart header="The for..of and for..in loops" +A small announcement for advanced readers. + +This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`. + +If you came to this article searching for other types of loops, here are the pointers: + +- See [for..in](info:object#forin) to loop over object properties. +- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects. + +Otherwise, please read on. +``` + +## The "while" loop +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu maqola faqat asosiy tsikllarni qamrab oladi: `while`, `do..while` va `for(..;..;..)`. @@ -119,12 +136,21 @@ for (let i = 0; i < 3; i++) { `for` ifodasini qism-qism ko'rib chiqamiz: +<<<<<<< HEAD | qism | | | | --------- | ----------- | --------------------------------------------------------------------------------------- | | begin | `let i = 0` | Tsiklga kirishda bir marta bajariladi. | | condition | `i < 3` | Har bir tsikl iteratsiyasidan oldin tekshiriladi. Agar yolg'on bo'lsa, tsikl to'xtaydi. | | body | `alert(i)` | Shart haqiqiy bo'lgan vaqtda qayta-qayta ishga tushadi. | | step | `i++` | Har bir iteratsiyada tanadan keyin bajariladi. | +======= +| part | | | +|-------|----------|----------------------------------------------------------------------------| +| begin | `let i = 0` | Executes once upon entering the loop. | +| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. | +| body | `alert(i)`| Runs again and again while the condition is truthy. | +| step| `i++` | Executes after the body on each iteration. | +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Umumiy tsikl algoritmi quyidagicha ishlaydi: @@ -188,9 +214,13 @@ alert(i); // 3, ko'rinadi, chunki tsikldan tashqarida e'lon qilingan ``` ```` +<<<<<<< HEAD ### Qismlarni tashlab qo'yish `for` ning har qanday qismini tashlab qo'yish mumkin. +======= +### Skipping parts +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, agar tsikl boshida hech narsa qilishga hojat bo'lmasa, `begin` ni tashlab qo'yishimiz mumkin. @@ -289,7 +319,12 @@ for (let i = 0; i < 10; i++) { Texnik nuqtai nazardan, bu yuqoridagi misolga bir xil. Albatta, biz `continue` ishlatish o'rniga kodni `if` blokiga o'rashimiz mumkin. +<<<<<<< HEAD Lekin yon ta'sir sifatida, bu yana bir darajali joylashish yaratdi (`alert` chaqiruvi jingalak qavslar ichida). Agar `if` ichidagi kod bir necha qatordan uzun bo'lsa, bu umumiy o'qish qobiliyatini kamaytirishi mumkin. +======= +But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability. +```` +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ````` @@ -306,7 +341,11 @@ if (i > 5) { } ``` +<<<<<<< HEAD ...va uni savol belgisi yordamida qayta yozsak: +======= +...and rewrite it using a question mark: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js no-beautify (i > 5) ? alert(i) : *!*continue*/!*; // continue bu yerda ruxsat etilmaydi @@ -341,6 +380,11 @@ Agar foydalanuvchi kiritishni bekor qilsa, jarayonni to'xtatish usuli kerak. _Yorliq_ - tsikldan oldin ikki nuqta bilan identifikator: +<<<<<<< HEAD +======= +A *label* is an identifier with a colon before a loop: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js labelName: for (...) { ... @@ -363,7 +407,11 @@ Quyidagi tsikldagi `break ` ifodasi yorliqqa chiqadi: } } +<<<<<<< HEAD alert('Tugadi!'); +======= +alert('Done!'); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` Yuqoridagi kodda `break outer` `outer` nomli yorliqni yuqorida qidiradi va o'sha tsikldan chiqadi. @@ -384,13 +432,22 @@ Yorliqlar koddagi ixtiyoriy joyga sakrashga ruxsat bermaydi. Masalan, buni qilish mumkin emas: +<<<<<<< HEAD +======= +For example, it is impossible to do this: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js break label; // pastdagi yorliqqa sakrash (ishlamaydi) label: for (...) ``` +<<<<<<< HEAD `break` direktivasi kod bloki ichida bo'lishi kerak. Texnik jihatdan, har qanday yorliqlangan kod bloki ishlaydi, masalan: +======= +A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js label: { @@ -400,7 +457,11 @@ label: { } ``` +<<<<<<< HEAD ...Garchi, vaqtning 99.9% da `break` tsikllar ichida ishlatiladi, yuqoridagi misollarda ko'rganimizdek. +======= +...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `continue` faqat tsikl ichidan mumkin. ```` diff --git a/1-js/02-first-steps/14-switch/article.md b/1-js/02-first-steps/14-switch/article.md index 0e778d577..2492fb46c 100644 --- a/1-js/02-first-steps/14-switch/article.md +++ b/1-js/02-first-steps/14-switch/article.md @@ -141,7 +141,11 @@ switch (a) { Endi `3` va `5` holat bir xil xabarni ko'rsatadi. +<<<<<<< HEAD Holatning "guruhlash" qobiliyati - bu `switch/case` ning `break`siz ishlashining yon ta'siri. Bu erda `3` holatning bajarilishi `(*)` satridan boshlanadi va `5` holatidan o'tadi, chunki `break` yo'q. +======= +The ability to "group" cases is a side effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Turi muhim diff --git a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md index d6c131f5b..7a5445802 100644 --- a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md +++ b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md @@ -1 +1,7 @@ +<<<<<<< HEAD Hech qanday farq yo'q. +======= +No difference! + +In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md index 3a5209f33..b12c2cba3 100644 --- a/1-js/02-first-steps/15-function-basics/article.md +++ b/1-js/02-first-steps/15-function-basics/article.md @@ -23,8 +23,13 @@ function showMessage() { `function` kalit so'zi birinchi o'rinda turadi, keyin _funksiya nomi_, so'ngra qavslar orasida _parametrlar_ ro'yxati (vergul bilan ajratilgan, yuqoridagi misolda bo'sh, keyinroq misollarni ko'ramiz) va nihoyat jingalak qavslar orasida funksiya kodi, "funksiya tanasi" deb ham ataladi. ```js +<<<<<<< HEAD function name(parameter1, parameter2, ...parameterN) { // tana +======= +function name(parameter1, parameter2, ... parameterN) { + // body +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 } ``` @@ -176,12 +181,21 @@ Qiymat funksiya parametri sifatida uzatilganda, u _argument_ deb ham ataladi. Boshqacha qilib aytganda, bu atamalarni to'g'ri qo'yish uchun: +<<<<<<< HEAD - Parametr - funksiya e'lonidagi qavslar ichida ko'rsatilgan o'zgaruvchi (bu e'lon vaqtidagi atama). - Argument - funksiya chaqirilganda uzatiladigan qiymat (bu chaqiruv vaqtidagi atama). +======= +- A parameter is the variable listed inside the parentheses in the function declaration (it's a declaration time term). +- An argument is the value that is passed to the function when it is called (it's a call time term). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biz funksiyalarni parametrlarini ko'rsatib e'lon qilamiz, keyin argumentlarni uzatib chaqiramiz. +<<<<<<< HEAD Yuqoridagi misolda shunday deyish mumkin: "`showMessage` funksiyasi ikkita parametr bilan e'lon qilingan, keyin ikkita argument bilan chaqirilgan: `from` va `"Salom"`". +======= +In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`". +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Standart qiymatlar @@ -205,7 +219,17 @@ function showMessage(from, *!*text = "matn berilmagan"*/!*) { showMessage("Ann"); // Ann: matn berilmagan ``` +<<<<<<< HEAD Endi agar `text` parametri uzatilmasa, u `"matn berilmagan"` qiymatini oladi. +======= +Now if the `text` parameter is not passed, it will get the value `"no text given"`. + +The default value also jumps in if the parameter exists, but strictly equals `undefined`, like this: + +```js +showMessage("Ann", undefined); // Ann: no text given +``` +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Parametr mavjud bo'lsa ham, lekin qat'iy ravishda `undefined` ga teng bo'lsa ham standart qiymat ishlaydi: @@ -230,10 +254,48 @@ Yuqoridagi misolda, agar `text` parametri berilsa, `anotherFunction()` umuman ch Boshqa tomondan, `text` yo'qolgan har safar u mustaqil ravishda chaqiriladi. ``` +<<<<<<< HEAD ````smart header="Eski JavaScript kodidagi standart parametrlar" Bir necha yil oldin JavaScript standart parametrlar sintaksisini qo'llab-quvvatlamagan edi. Shuning uchun odamlar ularni belgilashning boshqa usullarini ishlatganlar. Hozir biz ularni eski skriptlarda uchratishimiz mumkin. +======= +````smart header="Default parameters in old JavaScript code" +Several years ago, JavaScript didn't support the syntax for default parameters. So people used other ways to specify them. + +Nowadays, we can come across them in old scripts. + +For example, an explicit check for `undefined`: + +```js +function showMessage(from, text) { +*!* + if (text === undefined) { + text = 'no text given'; + } +*/!* + + alert( from + ": " + text ); +} +``` + +...Or using the `||` operator: + +```js +function showMessage(from, text) { + // If the value of text is falsy, assign the default value + // this assumes that text == "" is the same as no text at all + text = text || 'no text given'; + ... +} +``` +```` + + +### Alternative default parameters + +Sometimes it makes sense to assign default values for parameters at a later stage after the function declaration. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, `undefined` uchun aniq tekshiruv: @@ -283,7 +345,11 @@ function showMessage(text) { showMessage(); // bo'sh xabar ``` +<<<<<<< HEAD ...Yoki `||` operatoridan foydalanishimiz mumkin: +======= +...Or we could use the `||` operator: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js function showMessage(text) { @@ -461,7 +527,11 @@ Bu misollar prefikslarning umumiy ma'nolarini nazarda tutadi. Siz va jamoangiz b ```smart header="O'ta qisqa funksiya nomlari" *Juda tez-tez* ishlatiladigan funksiyalar ba'zan o'ta qisqa nomlarga ega. +<<<<<<< HEAD Masalan, [jQuery](https://jquery.com/) freymvorki `$` bilan funksiya aniqlaydi. [Lodash](https://lodash.com/) kutubxonasining asosiy funksiyasi `_` deb nomlangan. +======= +For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bular istisnolar. Umuman funksiya nomlari qisqa va tavsiflovchi bo'lishi kerak. ``` @@ -528,7 +598,11 @@ function name(vergul, bilan, ajratilgan, parametrlar) { Kodni toza va tushunish oson qilish uchun funksiyada asosan mahalliy o'zgaruvchilar va parametrlardan foydalanish tavsiya etiladi, tashqi o'zgaruvchilardan emas. +<<<<<<< HEAD Parametrlar oladigan, ular bilan ishlaydigan va natija qaytaradigan funksiyani tushunish har doim parametr olmaydigan, lekin yon ta'sir sifatida tashqi o'zgaruvchilarni o'zgartiradigan funksiyadan osondir. +======= +It is always easier to understand a function which gets parameters, works with them and returns a result than a function which gets no parameters, but modifies outer variables as a side effect. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Funksiyani nomlash: diff --git a/1-js/02-first-steps/16-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md index 1b975e48e..957c81f68 100644 --- a/1-js/02-first-steps/16-function-expressions/article.md +++ b/1-js/02-first-steps/16-function-expressions/article.md @@ -12,9 +12,15 @@ function sayHi() { Funksiya yaratishning yana bir sintaksisi bor, u _Funksiya ifodasi_ deb ataladi. +<<<<<<< HEAD Bu bizga har qanday ifoda o'rtasida yangi funksiya yaratishga imkon beradi. Masalan: +======= +It allows us to create a new function in the middle of any expression. + +For example: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let sayHi = function () { @@ -22,9 +28,25 @@ let sayHi = function () { }; ``` +<<<<<<< HEAD Bu yerda `sayHi` o'zgaruvchisi qiymat olayotganini ko'ramiz, yangi funksiya `function() { alert("Salom"); }` sifatida yaratilgan. Funksiya yaratish tayinlash ifodasining kontekstida (`=` ning o'ng tomonida) sodir bo'lgani uchun, bu *Funksiya ifodasi*dir. +======= +Here we can see a variable `sayHi` getting a value, the new function, created as `function() { alert("Hello"); }`. + +As the function creation happens in the context of the assignment expression (to the right side of `=`), this is a *Function Expression*. + +Please note, there's no name after the `function` keyword. Omitting a name is allowed for Function Expressions. + +Here we immediately assign it to the variable, so the meaning of these code samples is the same: "create a function and put it into the variable `sayHi`". + +In more advanced situations, that we'll come across later, a function may be created and immediately called or scheduled for a later execution, not stored anywhere, thus remaining anonymous. + +## Function is a value + +Let's reiterate: no matter how the function is created, a function is a value. Both examples above store a function in the `sayHi` variable. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 E'tibor bering, `function` kalit so'zidan keyin nom yo'q. Funksiya ifodalari uchun nomni tashlab qo'yish ruxsat etilgan. @@ -76,6 +98,7 @@ Bu yerda batafsil nima sodir bo'ladi: 2. `(2)` qator uni `func` o'zgaruvchisiga nusxalaydi. Yana e'tibor bering: `sayHi` dan keyin qavslar yo'q. Agar bo'lganida, `func = sayHi()` `sayHi()` _chaqiruv natijasini_ `func` ga yozar edi, `sayHi` _funksiyasining_ o'zini emas. 3. Endi funksiyani ham `sayHi()`, ham `func()` sifatida chaqirish mumkin. +<<<<<<< HEAD Birinchi qatorda `sayHi` ni e'lon qilish uchun Funksiya ifodasidan ham foydalanishimiz mumkin edi: ```js @@ -85,13 +108,29 @@ let sayHi = function () { }; let func = sayHi; //(2) +======= +We could also have used a Function Expression to declare `sayHi`, in the first line: + +```js +let sayHi = function() { // (1) create + alert( "Hello" ); +}; + +let func = sayHi; //(2) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 // ... ``` Hammasi bir xil ishlaydi. +<<<<<<< HEAD ````smart header="Nima uchun oxirida nuqta-vergul bor?" Siz hayron bo'lishingiz mumkin, nega Funksiya ifodalari oxirida nuqta-vergul `;` bor, lekin Funksiya e'lonlarida yo'q: +======= + +````smart header="Why is there a semicolon at the end?" +You might wonder, why do Function Expressions have a semicolon `;` at the end, but Function Declarations do not: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js function sayHi() { @@ -103,9 +142,15 @@ let sayHi = function() { }*!*;*/!* ``` +<<<<<<< HEAD Javob oddiy: Funksiya ifodasi bu yerda tayinlash ifodasining ichida `function(…) {…}` sifatida yaratilgan: `let sayHi = …;`. Nuqta-vergul `;` ifoda oxirida tavsiya etiladi, u funksiya sintaksisining qismi emas. Nuqta-vergul oddiy tayinlash uchun ham bo'lardi, masalan `let sayHi = 5;`, va funksiya tayinlash uchun ham bor. +======= +The answer is simple: a Function Expression is created here as `function(…) {…}` inside the assignment statement: `let sayHi = …;`. The semicolon `;` is recommended at the end of the statement, it's not a part of the function syntax. + +The semicolon would be there for a simpler assignment, such as `let sayHi = 5;`, and it's also there for a function assignment. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```` ## Callback funksiyalar @@ -145,13 +190,21 @@ function showCancel() { ask("Rozimisiz?", showOk, showCancel); ``` +<<<<<<< HEAD Amalda bunday funksiyalar juda foydali. Haqiqiy hayotdagi `ask` va yuqoridagi misol o'rtasidagi asosiy farq shundaki, haqiqiy funksiyalar foydalanuvchi bilan oddiy `confirm` dan ko'ra murakkabroq usullar bilan muloqot qiladi. Brauzerde bunday funksiyalar odatda chiroyli ko'rinishdagi savol oynasini chizadi. Lekin bu boshqa hikoya. +======= +In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such functions usually draw a nice-looking question window. But that's another story. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 **`ask` ning `showOk` va `showCancel` argumentlari _callback funksiyalar_ yoki shunchaki *callback*lar deb ataladi.** G'oya shundan iboratki, biz funksiyani uzatamiz va kerak bo'lsa keyinroq "chaqirib olinishini" kutamiz. Bizning holimizda `showOk` "ha" javobi uchun callback bo'ladi va `showCancel` "yo'q" javobi uchun. +<<<<<<< HEAD Funksiya ifodalaridan foydalanib ekvivalent, qisqaroq funksiya yozishimiz mumkin: +======= +We can use Function Expressions to write an equivalent, shorter function: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run no-beautify function ask(question, yes, no) { @@ -188,6 +241,7 @@ Birinchidan, sintaksis: kodni ularni qanday farqlash. - _Funksiya e'loni:_ asosiy kod oqimida alohida ifoda sifatida e'lon qilingan funksiya: +<<<<<<< HEAD ```js // Funksiya e'loni function sum(a, b) { @@ -196,6 +250,17 @@ Birinchidan, sintaksis: kodni ularni qanday farqlash. ``` - _Funksiya ifodasi:_ ifoda ichida yoki boshqa sintaksis konstruksiyasi ichida yaratilgan funksiya. Bu yerda funksiya "tayinlash ifodasining" `=` o'ng tomonida yaratilgan: +======= +- *Function Declaration:* a function, declared as a separate statement, in the main code flow: + + ```js + // Function Declaration + function sum(a, b) { + return a + b; + } + ``` +- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created on the right side of the "assignment expression" `=`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js // Funksiya ifodasi @@ -293,8 +358,13 @@ if (age < 18) { */!* // | function welcome() { // | +<<<<<<< HEAD alert("Salom!"); // | Funksiya e'loni e'lon qilingan } // | blokda hamma joyda mavjud +======= + alert("Hello!"); // | Function Declaration is available + } // | everywhere in the block where it's declared +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 // | *!* welcome(); // / (ishlaydi) @@ -303,7 +373,11 @@ if (age < 18) { } else { function welcome() { +<<<<<<< HEAD alert("Assalomu alaykum!"); +======= + alert("Greetings!"); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 } } @@ -362,7 +436,12 @@ welcome(); // endi yaxshi ```smart header="Funksiya e'loni va Funksiya ifodasini qachon tanlash kerak?" Qoida sifatida, funksiya e'lon qilish kerak bo'lganda, birinchi navbatda Funksiya e'loni sintaksisini ko'rib chiqish kerak. Bu bizga kodimizni qanday tashkil qilishda ko'proq erkinlik beradi, chunki biz bunday funksiyalarni ular e'lon qilinishidan oldin chaqirishimiz mumkin. +<<<<<<< HEAD Bu o'qish uchun ham yaxshiroq, chunki kodda `function f(…) {…}` ni qidirish `let f = function(…) {…};` dan osonroq. Funksiya e'lonlari ko'proq "ko'zga tashlanadigan". +======= +```smart header="When to choose Function Declaration versus Function Expression?" +As a rule of thumb, when we need to declare a function, the first thing to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ...Lekin agar Funksiya e'loni qandaydir sabab bilan bizga mos kelmasa yoki bizga shartli e'lon kerak bo'lsa (biz hozirgina misolni ko'rdik), u holda Funksiya ifodasidan foydalanish kerak. ``` diff --git a/1-js/02-first-steps/17-arrow-functions-basics/article.md b/1-js/02-first-steps/17-arrow-functions-basics/article.md index 1b659d54e..a8918798f 100644 --- a/1-js/02-first-steps/17-arrow-functions-basics/article.md +++ b/1-js/02-first-steps/17-arrow-functions-basics/article.md @@ -5,10 +5,14 @@ Funksiya yaratishning yana bir juda oddiy va qisqa sintaksisi bor, u ko'pincha F U "arrow funksiyalar" deb ataladi, chunki u quyidagicha ko'rinadi: ```js -let func = (arg1, arg2, ..., argN) => expression +let func = (arg1, arg2, ..., argN) => expression; ``` +<<<<<<< HEAD ...Bu `arg1..argN` argumentlarini qabul qiladigan `func` funksiyasini yaratadi, keyin ulardan foydalanib o'ng tomondagi `expression` ni baholaydi va natijasini qaytaradi. +======= +This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Boshqacha qilib aytganda, bu quyidagining qisqaroq versiyasi: @@ -33,7 +37,11 @@ let sum = function(a, b) { alert(sum(1, 2)); // 3 ``` +<<<<<<< HEAD Ko'rib turganingizdek, `(a, b) => a + b` `a` va `b` nomli ikkita argumentni qabul qiladigan funksiyani anglatadi. Bajarilishda u `a + b` ifadasini baholaydi va natijani qaytaradi. +======= +As you can see, `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - Agar bizda faqat bitta argument bo'lsa, parametrlar atrofidagi qavslarni tashlab qo'yish mumkin, bu uni yanada qisqaroq qiladi. @@ -48,7 +56,11 @@ Ko'rib turganingizdek, `(a, b) => a + b` `a` va `b` nomli ikkita argumentni qabu alert( double(3) ); // 6 ``` +<<<<<<< HEAD - Agar argumentlar bo'lmasa, qavslar bo'sh bo'ladi (lekin ular bo'lishi kerak): +======= +- If there are no arguments, parentheses are empty, but they must be present: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let sayHi = () => alert("Salom!"); @@ -63,8 +75,14 @@ Masalan, funksiyani dinamik yaratish uchun: ```js run let age = prompt("Yoshingiz necha?", 18); +<<<<<<< HEAD let welcome = age < 18 ? () => alert("Salom") : () => alert("Assalomu alaykum!"); +======= +let welcome = (age < 18) ? + () => alert('Hello!') : + () => alert("Greetings!"); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 welcome(); ``` @@ -75,9 +93,15 @@ Ular oddiy bir qatorli harakatlar uchun juda qulay, biz ko'p so'z yozishga danga ## Ko'p qatorli arrow funksiyalar +<<<<<<< HEAD Yuqoridagi misollar `=>` ning chap tomonidan argumentlarni oldi va ular bilan o'ng tomondagi ifodani baholadi. Ba'zan bizga biroz murakkabroq narsa kerak bo'ladi, masalan bir nechta ifodalar yoki iboralar. Bu ham mumkin, lekin biz ularni jingalak qavslar ichiga olishimiz kerak. Keyin ular ichida oddiy `return` dan foydalaning. +======= +The arrow functions that we've seen so far were very simple. They took arguments from the left of `=>`, evaluated and returned the right-side expression with them. + +Sometimes we need a more complex function, with multiple expressions and statements. In that case, we can enclose them in curly braces. The major difference is that curly braces require a `return` within them to return a value (just like a regular function does). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Quyidagicha: @@ -85,7 +109,11 @@ Quyidagicha: let sum = (a, b) => { // jingalak qavs ko'p qatorli funksiyani ochadi let result = a + b; *!* +<<<<<<< HEAD return result; // agar jingalak qavslardan foydalansak, aniq "return" kerak +======= + return result; // if we use curly braces, then we need an explicit "return" +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 */!* }; @@ -104,7 +132,14 @@ Hozircha biz arrow funksiyalarni bir qatorli harakatlar va callbacklar uchun ish ## Xulosa +<<<<<<< HEAD Arrow funksiyalar bir qatorlilar uchun qulay. Ular ikki xil bo'ladi: 1. Jingalak qavslarsiz: `(...args) => expression` -- o'ng tomon ifoda: funksiya uni baholaydi va natijani qaytaradi. 2. Jingalak qavslar bilan: `(...args) => { body }` -- qavslar bizga funksiya ichida bir nechta iboralarni yozishga imkon beradi, lekin biror narsani qaytarish uchun aniq `return` kerak. +======= +Arrow functions are handy for simple actions, especially for one-liners. They come in two flavors: + +1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result. Parentheses can be omitted, if there's only a single argument, e.g. `n => n*2`. +2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md index 087e588db..a20dfd1ce 100644 --- a/1-js/02-first-steps/18-javascript-specials/article.md +++ b/1-js/02-first-steps/18-javascript-specials/article.md @@ -54,7 +54,11 @@ Zamonaviy JavaScript-ning barcha xususiyatlarini to'liq yoqish uchun skriptlarni Direktiva skriptning yuqorisida yoki funksiya tanasining boshida bo'lishi kerak. +<<<<<<< HEAD `"use strict"` bo'lmasa ham, hamma narsa ishlaydi, lekin ba'zi xususiyatlar eski uslubda, "mos" tarzda ishlaydi. Biz odatda zamonaviy xatti-harakatni afzal ko'ramiz. +======= +Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Tilning ba'zi zamonaviy xususiyatlari (kelajakda o'rganadigan sinflar kabi) qat'iy rejimni bilvosita yoqadi. @@ -105,6 +109,7 @@ Batafsil: va . Biz brauzerni ish muhiti sifatida ishlatamoqdamiz, shuning uchun asosiy UI funksiyalar quyidagicha bo'ladi: [`prompt(question, [default])`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) +<<<<<<< HEAD : `question` so'rash va tashrif buyuruvchi kiritgan narsani yoki "bekor qilish"ni bossalar `null` ni qaytarish. [`confirm(question)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) @@ -112,6 +117,15 @@ Biz brauzerni ish muhiti sifatida ishlatamoqdamiz, shuning uchun asosiy UI funks [`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert) : `message` ni chiqarish. +======= +: Ask a `question`, and return either what the visitor entered or `null` if they clicked "cancel". + +[`confirm(question)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) +: Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`. + +[`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert) +: Output a `message`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu funksiyalarning barchasi _modal_, ular kod bajarilishini to'xtatadi va tashrif buyuruvchi javob berguncha sahifa bilan o'zaro ta'sirni oldini oladi. @@ -144,8 +158,13 @@ Arifmetik Tayinlashlar : Oddiy tayinlash: `a = b` va birlashtirilganlar `a *= 2` kabi. +<<<<<<< HEAD Bitli : Bitli operatorlar eng past, bit darajasida 32-bitli butun sonlar bilan ishlaydi: kerak bo'lganda [hujjatlarga](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) qarang. +======= +Bitwise +: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) when they are needed. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shartli : Uchta parametrli yagona operator: `cond ? resultA : resultB`. Agar `cond` haqiqiy bo'lsa, `resultA` ni qaytaradi, aks holda `resultB` ni. @@ -256,9 +275,15 @@ JavaScript-da funksiya yaratishning uchta usulini ko'rib chiqdik: 3. Arrow funksiyalar: +<<<<<<< HEAD ```js // o'ng tomonda ifoda let sum = (a, b) => a + b; +======= + ```js + // expression on the right side + let sum = (a, b) => a + b; +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 // yoki { ... } bilan ko'p qatorli sintaksis, bu yerda return kerak: let sum = (a, b) => { diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md index 81195d067..6199b98c7 100644 --- a/1-js/03-code-quality/01-debugging-chrome/article.md +++ b/1-js/03-code-quality/01-debugging-chrome/article.md @@ -38,7 +38,11 @@ Agar biz `Esc` tugmachasini bossak, u holda konsol quyida ochiladi. Biz u erga b Ifoda bajarilgandan so'ng uning natijasi quyida ko'rsatiladi. +<<<<<<< HEAD Masalan, bu yerda `1+2` ning natijasi `3` ga teng, va `hello("debugger")` hech narsa qaytarmaydi, shuning uchun natijasi `undefined`: +======= +For example, here `1+2` results in `3`, while the function call `hello("debugger")` returns nothing, so the result is `undefined`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ![](chrome-sources-console.svg) @@ -58,10 +62,15 @@ Kod to'xtatib turilsa, biz mavjud o'zgaruvchanlarni tekshirib ko'rishimiz, konso Biz har doim o'ng oynada to'xtash nuqtalarining ro'yxatini topishimiz mumkin. Bu turli xil fayllarda juda ko'p to'xtash nuqtalari mavjud bo'lganda foydalidir. Bu bizga quyidagilarga imkon beradi: +<<<<<<< HEAD - Koddagi to'xtash nuqtasiga tezda o'tish (o'ng oynada uni bosish orqali). - Tekshirish nuqtasini olib tashlab, uni o'chirib qo'yish. - Sichqonchaning o'ng tugmachasini bosib, remove(o'chirish)-ni tanlab, to'xtash nuqtasini olib tashlash. - ...Va hokazo. +======= +```smart header="Conditional breakpoints" +*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression, that you should provide when you create it, is truthy. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="Shartli to'xtash nuqtalari" Satr raqamidagi *o'ng tugmachani* bosish *shartli* to'xtash nuqtasini yaratishga imkon beradi. Bu faqat berilgan ifoda haqiqat bo'lganda boshlanadi. @@ -69,7 +78,11 @@ Satr raqamidagi *o'ng tugmachani* bosish *shartli* to'xtash nuqtasini yaratishga Bu faqat ma'lum bir o'zgaruvchan qiymat yoki funktsiya parametrlari uchun to'xtashimiz kerak bo'lganda qulay. ``` +<<<<<<< HEAD ## Koddagi nosozliklarni tuzatuvchi buyrug'i +======= +## The command "debugger" +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Kodni quyidagi kabi `koddagi nosozliklarni tuzatuvchi` buyrug'i yordamida to'xtatib turishimiz mumkin: @@ -85,9 +98,13 @@ function hello(name) { } ``` +<<<<<<< HEAD Bu biz kod muharririda bo'lganimizda va brauzerga o'tishni xohlamasak va to'xtash nuqtasini o'rnatish uchun ishlab chiquvchi vositalarida skriptni qidirishni istamasak, bu juda qulay. ## Kodni to'xtatib turing va atrofga nazar tashlang +======= +Such command works only when the development tools are open, otherwise the browser ignores it. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bizning misolimizda sahifani yuklash paytida `hello()` chaqiriladi, shuning uchun koddagi nosozliklarni tuzatuvchi faollashtirishning eng oson usuli bu sahifani qayta yuklashdir. Keling, `key:F5` (Windows, Linux) yoki `key:Cmd+R` (Mac) bosing. @@ -99,7 +116,11 @@ Iltimos, ma'lumotlar ochiladigan sahifalarni o'ng tomonga oching (o'qlar bilan b 1. **`Watch` -- har qanday ifodalar uchun joriy qiymatlarni ko'rsatadi.** +<<<<<<< HEAD Siz ortiqcha `+` tugmachasini bosishingiz va ifodani kiritishingiz mumkin. Koddagi nosozliklarni tuzatuvchi har qanday vaqtda o'z qiymatini ko'rsatadi, uni bajarish jarayonida avtomatik ravishda qayta hisoblab chiqadi. +======= + You can click the plus `+` and input an expression. The debugger will show its value, automatically recalculating it in the process of execution. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 2. **`Call Stack` -- ulanish chaqiruvlar zanjirini ko'rsatadi.** @@ -136,6 +157,7 @@ O'ng oynaning yuqori qismida buning uchun tugmalar mavjud. Keling, ularni o'rgan -- qadam qo'yish, tezkor tugma `key:F11`. : Oldingi bilan bir xil, ammo ichki qadam vazifalariga "qadam qo'yadi". Buni bosish barcha skript harakatlariga birma-bir qadam qo'yadi. +<<<<<<< HEAD -- joriy funktsiyani oxirigacha bajarishni davom etish, tezkor tugma `key:Shift+F11`. : Ijro etilish joriy funktsiyalarning oxirgi satrda to'xtaydi. Biz tasodifan yordamida ichki chaqiruvni kiritganimizda bu juda qulay, ammo bu bizni qiziqtirmaydi va biz oxirigacha davom etishni imkoni boricha tezda xohlaymiz. @@ -144,11 +166,40 @@ O'ng oynaning yuqori qismida buning uchun tugmalar mavjud. Keling, ularni o'rgan -- xatolik yuz berganda avtomatik to'xtatishni yoqish/o'chirish. : Yoqilganda va dasturchi vositalari ochiq bo'lsa, skript xatosi avtomatik ravishda bajarilishini to'xtatadi. Keyin nima o'zgarganligini ko'rish uchun o'zgaruvchanlarni tahlil qilishimiz mumkin. Shunday qilib, agar bizning skriptimiz xato bilan to'xtasa, biz koddagi nosozliklarni tuzatuvchi vositasini ochib, ushbu parametrni yoqib, sahifani qayta yuklashimiz mumkin, u qayerda to'xtashini va o'sha paytda qanday qiymatda ekanligini bilib olishimiz mumkin. +======= + -- "Step over": run the next command, but *don't go into a function*, hotkey `key:F10`. +: Similar to the previous "Step" command, but behaves differently if the next statement is a function call (not a built-in, like `alert`, but a function of our own). + + If we compare them, the "Step" command goes into a nested function call and pauses the execution at its first line, while "Step over" executes the nested function call invisibly to us, skipping the function internals. + + The execution is then paused immediately after that function call. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="Bu erda davom eting" Kod satriga sichqonchaning o'ng tugmasi bilan bosish kontekst menyusini "Bu erda davom eting" ochadi. +<<<<<<< HEAD Bu biz bir necha qadam oldinga siljishni xohlaganimizda qulay, ammo biz to'xtash nuqtasini o'rnatishga dangasa bo'lsak. +======= + -- "Step into", hotkey `key:F11`. +: That's similar to "Step", but behaves differently in case of asynchronous function calls. If you're only starting to learn JavaScript, then you can ignore the difference, as we don't have asynchronous calls yet. + + For the future, just note that "Step" command ignores async actions, such as `setTimeout` (scheduled function call), that execute later. The "Step into" goes into their code, waiting for them if necessary. See [DevTools manual](https://developers.google.com/web/updates/2018/01/devtools#async) for more details. + + -- "Step out": continue the execution till the end of the current function, hotkey `key:Shift+F11`. +: Continue the execution and stop it at the very last line of the current function. That's handy when we accidentally entered a nested call using , but it does not interest us, and we want to continue to its end as soon as possible. + + -- enable/disable all breakpoints. +: That button does not move the execution. Just a mass on/off for breakpoints. + + -- enable/disable automatic pause in case of an error. +: When enabled, if the developer tools is open, an error during the script execution automatically pauses it. Then we can analyze variables in the debugger to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment. + +```smart header="Continue to here" +Right click on a line of code opens the context menu with a great option called "Continue to here". + +That's handy when we want to move multiple steps forward to the line, but we're too lazy to set a breakpoint. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Konsolga chiqarish @@ -172,9 +223,13 @@ Agar bizning kodimizga kiritish yetarli bo'lsa, biz nima sodir bo'layotganini ko Ko'rib turganimizdek, skriptni to'xtatib turishning uchta asosiy usuli mavjud: +<<<<<<< HEAD 1. To'xtash nuqtasi. 2. "Koddagi nosozliklarni tuzatuvchi" ifodalari. 3. Xato (agar dasturchi vositalari ochiq bo'lsa va tugmasi "yoqilgan" bo'lsa) +======= +When paused, we can debug: examine variables and trace the code to see where the execution goes wrong. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Keyin biz o'zgaruvchanlarni ko'rib chiqamiz va bajarilish qayerda noto'g'ri ketayotganini bilib olamiz. diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md index 9321a2f5e..e509483a7 100644 --- a/1-js/03-code-quality/02-coding-style/article.md +++ b/1-js/03-code-quality/02-coding-style/article.md @@ -281,11 +281,19 @@ Ularning eng yaxshi tomoni shundaki, uslublarni tekshirishda o'zgaruvchan yoki f Bu erda eng taniqli linting vositalari: +<<<<<<< HEAD - [JSLint](http://www.jslint.com/) -- birinchi lintlardan biri. - [JSHint](http://www.jshint.com/) -- JSLint-dan ko'proq sozlamalar. - [ESLint](http://eslint.org/) -- ehtimol eng yangi. Ularning barchasi ishni bajarishi mumkin. Muallif [ESLint](http://eslint.org/) dan foydalanadi. +======= +- [JSLint](https://www.jslint.com/) -- one of the first linters. +- [JSHint](https://jshint.com/) -- more settings than JSLint. +- [ESLint](https://eslint.org/) -- probably the newest one. + +All of them can do the job. The author uses [ESLint](https://eslint.org/). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Aksariyat linterslar ko'plab taniqli muharrirlar bilan birlashtirilgan: muharriridagi plaginni yoqing va uslubni sozlang. @@ -315,7 +323,11 @@ Masalan, ESLint uchun quyidagilarni bajarishingiz kerak: Bu erda `"extends"` direktivasi "eslint:recommended" sozlamalar to'plamiga asoslanganligini bildiradi. Shundan so'ng biz o'zimiznikini aniqlaymiz. +<<<<<<< HEAD Shuningdek, uslublar qoidalari to'plamlarini Internetdan yuklab olish va oldingilarni o'rniga ularni kengaytirish mumkin. O'rnatish haqida batafsil ma'lumot uchun ga qarang. +======= +It is also possible to download style rule sets from the web and extend them instead. See for more details about installation. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shuningdek, ba'zi bir IDE-larda ichki linting mavjud, bu qulay, ammo ESLint kabi moslashtirilmaydi. diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md index 0b3885c8a..d20bce742 100644 --- a/1-js/03-code-quality/03-comments/article.md +++ b/1-js/03-code-quality/03-comments/article.md @@ -142,7 +142,11 @@ Funktsiyadan foydalanishni hujjatlashtiring Aytgancha, [WebStorm](https://www.jetbrains.com/webstorm/) kabi ko'plab tahrirlovchilar ularni ham tushunishlari mumkin va ularni avtomatik to'ldirish va ba'zi bir avtomatik kodlarni tekshirish uchun ishlatishlari mumkin. +<<<<<<< HEAD Shuningdek, [JSDoc 3] (https://github.com/jsdoc3/jsdoc) kabi vositalar mavjud, ular izohlardan HTML-hujjatlarni yaratishlari mumkin. JSDoc haqida ko'proq ma'lumotni sahifasida o'qishingiz mumkin. +======= +Also, there are tools like [JSDoc 3](https://github.com/jsdoc/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Nima uchun vazifa shu tarzda hal qilinadi? : Yozilgan kod muhim. Ammo nima yozilganini tushunish uchun _yozilmagan_ narsalar yanada muhimroq bo'lishi mumkin. Nima uchun vazifa aynan shu tarzda hal qilinadi? Kod hech qanday javob bermaydi. diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md index d4fa5b2ab..4d82402ce 100644 --- a/1-js/03-code-quality/05-testing-mocha/article.md +++ b/1-js/03-code-quality/05-testing-mocha/article.md @@ -50,9 +50,14 @@ describe("pow", function () { Spetsifikatsiyada yuqorida ko'rishingiz mumkin bo'lgan uchta asosiy qurilish bloklari mavjud: +<<<<<<< HEAD `describe("sarlavha", function() { ... })` : What functionality we're describing. Uses to group "workers" -- the `it` blocks. In our case we're describing the function `pow`. Biz qaysi funktsiyalarni tasvirlaymiz. Bizning holatda biz `pow` funktsiyasini tasvirlaymiz. Ishchi otlarni - `it` bloklarni guruhlash uchun ishlatiladi. +======= +`describe("title", function() { ... })` +: What functionality we're describing? In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `it("sarlavha", function() { ... })` : `it` blokining birinchi argumentida biz _inson tilida_ funktsiyadan foydalanishning aniq usulini tasvirlaymiz, ikkinchisida esa bu ishni sinab ko'radigan funktsiyani yozamiz. @@ -68,6 +73,7 @@ Biz qaysi funktsiyalarni tasvirlaymiz. Bizning holatda biz `pow` funktsiyasini t Rivojlanish oqimi odatda quyidagicha ko'rinadi: +<<<<<<< HEAD 1. Dastlabki spetsifikatsiya asosiy funksiyani tekshiradigan testlar bilan yoziladi. 2. Dastlabki dastur yaratiladi. 3. Uning ishlashini tekshirish uchun biz spetsifikatsiyani boshqaradigan sinov tizimini [Mocha](http://mochajs.org/) (yaqinda batafsil ma'lumot) ishlatamiz. Xatolar ko'rsatiladi. Hamma narsa ishlamaguncha biz tuzatishlar kiritamiz. @@ -75,12 +81,25 @@ Rivojlanish oqimi odatda quyidagicha ko'rinadi: 5. Sinov kodida hali amalga oshirilmagan bo'lishi mumkin bo'lgan foydalanishning yangi usullarini qo'shamiz. Testlar "tushib" (xatolar berish) boshlaydi. 6. 3-ga o'ting, testlar xato qilmaguncha dasturni yangilang. 7. Dastur tayyor bo'lguncha 3-6 bosqichlarni takrorlang. +======= +1. An initial spec is written, with tests for the most basic functionality. +2. An initial implementation is created. +3. To check whether it works, we run the testing framework [Mocha](https://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works. +4. Now we have a working initial implementation with tests. +5. We add more use cases to the spec, probably not yet supported by the implementations. Tests start to fail. +6. Go to 3, update the implementation till tests give no errors. +7. Repeat steps 3-6 till the functionality is ready. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shunday qilib, rivojlanish _takrorlanadigan_. Biz spetsifikatsiyani yozamiz, uni amalga oshiramiz, testlar o'tganligiga ishonch hosil qilamiz, so'ngra ko'proq testlarni yozamiz, ularning ishlashiga ishonch hosil qilamiz va hokazo. Oxirida bizda ishlaydigan dastur ham, testlar ham mavjud. Bizning holatlarimizda birinchi qadam tugallandi: bizda `pow` uchun boshlang'ich spetsifikatsiya mavjud. Keling, amalga oshiraylik. Ammo bundan oldin testlarning ishlayotganligini ko'rish uchun spetsifikatsiyani "nolga" o'tkazamiz (barchasi muvaffaqiyatsiz bo'ladi). +<<<<<<< HEAD ## Amaldagi spetsifikatsiya +======= +The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use a few JavaScript libraries to run the tests, just to see that they are working (they will all fail). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu qo'llanmada biz testlar uchun quyidagi JavaScript kutubxonalaridan foydalanamiz: @@ -88,7 +107,13 @@ Bu qo'llanmada biz testlar uchun quyidagi JavaScript kutubxonalaridan foydalanam - [Chai](http://chaijs.com) -- ko'plab tasdiqlar bilan kutubxona. Bu juda ko'p tasdiqlardan foydalanishga imkon beradi, hozirda bizga faqat `assert.equal` kerak. - [Sinon](http://sinonjs.org/) -- funksiyalarni kuzatish, ichki xususiyatlarni taqlid qilish va boshqa ko'p narsalarni ko'rish imkonini beruvchi kutubxona. Keyinchalik biz uchun foydali bo'ladi. +<<<<<<< HEAD Ushbu kutubxonalar brauzerda ham, serverda ham sinov uchun javob beradi. Bu erda biz brauzer variantini ko'rib chiqamiz. +======= +- [Mocha](https://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests. +- [Chai](https://www.chaijs.com/) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`. +- [Sinon](https://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ushbu framework-lar va `pow` spetsifikatsiya bilan to'liq HTML-sahifa: @@ -333,6 +358,7 @@ Yangi qo'shilgan testlar muvaffaqiyatsiz tugadi, chunki bizning dasturimiz ularn ```smart header="Boshqa tasdiqlar" +<<<<<<< HEAD Iltimos, `assert.isNaN` tasdiqiga e'tibor bering: u `NaN` ni tekshiradi. Chai-da boshqa tasdiqlar ham mavjud, masalan: @@ -343,6 +369,16 @@ Chai-da boshqa tasdiqlar ham mavjud, masalan: - `assert.isTrue(qiymat)` -- `qiymat === true` tekshiradi - `assert.isFalse(qiymat)` -- `qiymat === false` tekshiradi - ...to'liq ro'yxat [hujjatlar](http://chaijs.com/api/assert/) +======= +There are other assertions in [Chai](https://www.chaijs.com/) as well, for instance: + +- `assert.equal(value1, value2)` -- checks the equality `value1 == value2`. +- `assert.strictEqual(value1, value2)` -- checks the strict equality `value1 === value2`. +- `assert.notEqual`, `assert.notStrictEqual` -- inverse checks to the ones above. +- `assert.isTrue(value)` -- checks that `value === true` +- `assert.isFalse(value)` -- checks that `value === false` +- ...the full list is in the [docs](https://www.chaijs.com/api/assert/) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` Shunday qilib, biz `pow` ga bir nechta satr qo'shishimiz kerak: diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md index 8c2f2a17a..f70559ea8 100644 --- a/1-js/03-code-quality/06-polyfills/article.md +++ b/1-js/03-code-quality/06-polyfills/article.md @@ -2,13 +2,23 @@ JavaScript tili barqaror ravishda rivojlanib boradi. Tilga yangi takliflar muntazam ravishda paydo bo'ladi, ular tahlil qilinadi va agar munosib deb topilsa, dagi ro'yxatga qo'shiladi va keyin [spetsifikatsiya](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/)ga o'tadi. +<<<<<<< HEAD JavaScript dvigatellari ortidagi jamoalar birinchi navbatda nimani amalga oshirish haqida o'zlarining g'oyalariga ega. Ular loyiha holatidagi takliflarni amalga oshirishga qaror qilishlari va spetsifikatsiyada allaqachon mavjud bo'lgan narsalarni kechiktirishlari mumkin, chunki ular kamroq qiziqarli yoki shunchaki bajarish qiyinroq. +======= +The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at and then progress to the [specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shuning uchun dvigatel standartning faqat bir qismini amalga oshirishi odatiy hol. +<<<<<<< HEAD Til xususiyatlarini qo'llab-quvvatlashning hozirgi holatini ko'rish uchun yaxshi sahifa (u katta, bizda hali o'rganish uchun ko'p narsa bor). Dasturchilar sifatida biz eng so'nggi xususiyatlardan foydalanishni xohlaymiz. Ko'proq yaxshi narsa - yaxshiroq! +======= +So it's quite common for an engine to implement only part of the standard. + +A good page to see the current state of support for language features is (it's big, we have a lot to study yet). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Boshqa tomondan, hali so'nggi xususiyatlarni tushunmaydigan eski dvigatellarda zamonaviy kodimiz qanday ishlashini ta'minlash mumkin? @@ -23,7 +33,11 @@ Bu bobda bizning maqsadimiz ularning qanday ishlashini va veb-dasturlashdagi o'r [Transpailer](https://en.wikipedia.org/wiki/Source-to-source_compiler) - bu manba kodini boshqa manba kodiga tarjima qiladigan maxsus dastur. U zamonaviy kodni tahlil qilishi ("o'qish va tushunish") va uni eski sintaksis konstruksiyalaridan foydalanib qayta yozishi mumkin, shunda u eski dvigatellarda ham ishlaydi. +<<<<<<< HEAD Masalan, 2020 yilgacha JavaScript-da "nullish coalescing operator" `??` mavjud emas edi. Shunday qilib, agar tashrif buyuruvchi eski brauzerni ishlatsa, u `height = height ?? 100` kabi kodni tushunishda muvaffaqiyatsizlikga uchraydi. +======= +A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that translates source code to another source code. It can parse ("read and understand") modern code and rewrite it using older syntax constructs, so that it'll also work in outdated engines. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Transpailer bizning kodimizni tahlil qiladi va `height ?? 100` ni `(height !== undefined && height !== null) ? height : 100` ga qayta yozadi. @@ -39,9 +53,15 @@ Endi qayta yozilgan kod eski JavaScript dvigatellari uchun mos keladi. Odatda, dasturchi transpailer ni o'z kompyuterida ishga tushiradi va keyin transpaile qilingan kodni serverga joylashtiradi. +<<<<<<< HEAD Nomlar haqida gapiradigan bo'lsak, [Babel](https://babeljs.io) eng mashhur transpailerlardan biridir. [Webpack](https://webpack.js.org/) kabi zamonaviy loyiha qurilish tizimlari har bir kod o'zgarishida transpailer ni avtomatik ravishda ishga tushirish vositasini taqdim etadi, shuning uchun uni rivojlanish jarayoniga integratsiya qilish juda oson. +======= +Speaking of names, [Babel](https://babeljs.io) is one of the most prominent transpilers out there. + +Modern project build systems, such as [webpack](https://webpack.js.org/), provide a means to run a transpiler automatically on every code change, so it's very easy to integrate into the development process. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Polyfilllar @@ -69,21 +89,39 @@ if (!Math.trunc) { } ``` +<<<<<<< HEAD JavaScript juda dinamik tildir. Skriptlar har qanday funktsiyani, hatto o'rnatilganlarni ham qo'shishi/o'zgartirishi mumkin. Qiziqarli polyfill kutubxonalaridan biri [core-js](https://github.com/zloirock/core-js) bo'lib, u keng xususiyatlar spektrini qo'llab-quvvatlaydi va faqat kerakli xususiyatlarni qo'shishga imkon beradi. ## Xulosa +======= +JavaScript is a highly dynamic language. Scripts may add/modify any function, even built-in ones. + +One interesting polyfill library is [core-js](https://github.com/zloirock/core-js), which supports a wide range of features and allows you to include only the ones you need. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ushbu bobda biz sizni zamonaviy va hatto "eng yangi" til xususiyatlarini o'rganishga undashni xohlaymiz, hatto ular hali JavaScript dvigatellari tomonidan yaxshi qo'llab-quvvatlanmasa ham. Faqat transpailer (zamonaviy sintaksis yoki operatorlardan foydalansangiz) va polyfilllardan (etishmayotgan funktsiyalarni qo'shish uchun) foydalanishni unutmang. Ular kodning ishlashini ta'minlaydi. +<<<<<<< HEAD Masalan, keyinroq JavaScript bilan tanishganingizdan keyin, [babel-loader](https://github.com/babel/babel-loader) plagini bilan [webpack](https://webpack.js.org/) asosida kod qurilish tizimini o'rnatishingiz mumkin. Turli xususiyatlarni qo'llab-quvvatlashning hozirgi holatini ko'rsatadigan yaxshi resurslar: - - sof JavaScript uchun. - - brauzer bilan bog'liq funktsiyalar uchun. +======= +Just don't forget to use a transpiler (if using modern syntax or operators) and polyfills (to add functions that may be missing). They'll ensure that the code works. + +For example, later when you're familiar with JavaScript, you can setup a code build system based on [webpack](https://webpack.js.org/) with the [babel-loader](https://github.com/babel/babel-loader) plugin. + +Good resources that show the current state of support for various features: +- - for pure JavaScript. +- - for browser-related functions. + +P.S. Google Chrome is usually the most up-to-date with language features, try it if a tutorial demo fails. Most tutorial demos work with any modern browser though. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 P.S. Google Chrome odatda til xususiyatlari bilan eng yangilangan, agar o'quv qo'llanmasining demo ishlamasa, uni sinab ko'ring. Ko'pchilik o'quv qo'llanmasi demolari har qanday zamonaviy brauzer bilan ishlaydi. diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index 1378a8c8a..b29cf442f 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -44,7 +44,11 @@ Natijada olingan `user` obyektini "name" va "age" yorliqlari bilan belgilangan i ![user object](object-user.svg) +<<<<<<< HEAD Biz undan istalgan vaqtda fayllarni qo'shish, olib tashlash va o'qishimiz mumkin. +======= +We can add, remove and read files from it at any time. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Xossa qiymatlari nuqta notation orqali kirish mumkin: @@ -62,7 +66,11 @@ user.isAdmin = true; ![user object 2](object-user-isadmin.svg) +<<<<<<< HEAD Xossani olib tashlash uchun `delete` operatoridan foydalanishimiz mumkin: +======= +To remove a property, we can use the `delete` operator: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js delete user.age; @@ -203,13 +211,21 @@ let bag = { }; ``` +<<<<<<< HEAD Kvadrat qavslar nuqta notationdan ancha kuchliroq. Ular har qanday xossa nomlari va o'zgaruvchilarga ruxsat beradi. Lekin ular yozish uchun ham noqulayroq. +======= +Square brackets are much more powerful than dot notation. They allow any property names and variables. But they are also more cumbersome to write. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shuning uchun ko'p hollarda, xossa nomlari ma'lum va oddiy bo'lganda, nuqta ishlatiladi. Va agar bizga murakkabroq narsa kerak bo'lsa, kvadrat qavslarga o'tamiz. ## Xossa qiymati qisqartmasi +<<<<<<< HEAD Haqiqiy kodda biz ko'pincha mavjud o'zgaruvchilarni xossa nomlari uchun qiymat sifatida ishlatamiz. +======= +In real code, we often use existing variables as values for property names. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan: @@ -255,7 +271,13 @@ let user = { Bizga ma'lumki, o'zgaruvchi "for", "let", "return" va hokazo kabi tilning zahiralangan so'zlariga teng nomga ega bo'la olmaydi. +<<<<<<< HEAD Lekin obyekt xossasi uchun bunday cheklov yo'q: +======= +As we already know, a variable cannot have a name equal to one of the language-reserved words like "for", "let", "return" etc. + +But for an object property, there's no such restriction: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run // bu xossalar yaxshi @@ -327,7 +349,11 @@ alert("blabla" in user); // false, user.blabla mavjud emas E'tibor bering, `in` ning chap tomonida _xossa nomi_ bo'lishi kerak. Bu odatda qo'shtirnoqli satr. +<<<<<<< HEAD Agar qo'shtirnoqlarni tashlab qo'ysak, bu o'zgaruvchi tekshirilishi kerak bo'lgan haqiqiy nomni o'z ichiga olishi kerakligini anglatadi. Masalan: +======= +If we omit quotes, that means a variable should contain the actual name to be tested. For instance: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let user = { age: 30 }; @@ -358,7 +384,11 @@ Bunday vaziyatlar juda kam uchraydi, chunki `undefined` aniq tayinlanmasligi ker ## "for..in" tsikli [#forin] +<<<<<<< HEAD Obyektning barcha kalitlari bo'ylab yurish uchun tsiklning maxsus shakli mavjud: `for..in`. Bu biz ilgari o'rgangan `for(;;)` konstruksiyasidan butunlay boshqa narsa. +======= +## The "for..in" loop [#forin] +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Sintaksis: @@ -413,7 +443,11 @@ for (let code in codes) { */!* ``` +<<<<<<< HEAD Obyekt foydalanuvchiga variantlar ro'yxatini taklif qilish uchun ishlatilishi mumkin. Agar biz asosan nemis auditoriyasi uchun sayt yaratayotgan bo'lsak, ehtimol `49` birinchi bo'lishini xohlaymiz. +======= +The object may be used to suggest a list of options to the user. If we're making a site mainly for a German audience then we probably want `49` to be the first. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Lekin kodni ishga tushirsak, butunlay boshqa rasmni ko'ramiz: @@ -425,6 +459,7 @@ Telefon kodlari o'sish tartibida saralanadi, chunki ular butun sonlar. Shuning u ````smart header="Butun son xossalari? Bu nima?" Bu yerdagi "butun son xossasi" atamasi o'zgarishsiz butun songa aylantirilishi va undan qaytarilishi mumkin bo'lgan satrni anglatadi. +<<<<<<< HEAD Shunday qilib, `"49"` butun son xossa nomi, chunki u butun son raqamiga aylantirilganda va orqaga qaytarilganda, u bir xil bo'lib qoladi. Lekin `"+49"` va `"1.2"` emas: ```js run @@ -433,6 +468,16 @@ Shunday qilib, `"49"` butun son xossa nomi, chunki u butun son raqamiga aylantir alert( String(Math.trunc(Number("49"))) ); // "49", bir xil, butun son xossasi alert( String(Math.trunc(Number("+49"))) ); // "49", bir xil emas "+49" ⇒ butun son xossasi emas alert( String(Math.trunc(Number("1.2"))) ); // "1", bir xil emas "1.2" ⇒ butun son xossasi emas +======= +So, `"49"` is an integer property name, because when it's transformed to an integer number and back, it's still the same. But `"+49"` and `"1.2"` are not: + +```js run +// Number(...) explicitly converts to a number +// Math.trunc is a built-in function that removes the decimal part +alert( String(Math.trunc(Number("49"))) ); // "49", same, integer property +alert( String(Math.trunc(Number("+49"))) ); // "49", not same "+49" ⇒ not integer property +alert( String(Math.trunc(Number("1.2"))) ); // "1", not same "1.2" ⇒ not integer property +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ```` @@ -479,8 +524,14 @@ Obyektlar bir nechta maxsus xususiyatlarga ega assotsiativ massivlardir. Ular xossalarni (kalit-qiymat juftliklarini) saqlaydi, bu yerda: +<<<<<<< HEAD - Xossa kalitlari satrlar yoki symbollar bo'lishi kerak (odatda satrlar). - Qiymatlar har qanday tipda bo'lishi mumkin. +======= +To access a property, we can use: +- The dot notation: `obj.property`. +- Square brackets notation `obj["property"]`. Square brackets allow taking the key from a variable, like `obj[varWithKey]`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Xossaga kirish uchun biz quyidagilardan foydalanishimiz mumkin: diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md index 60f55e738..5b226fbb8 100644 --- a/1-js/04-object-basics/02-object-copy/article.md +++ b/1-js/04-object-basics/02-object-copy/article.md @@ -37,7 +37,11 @@ Va u xotirada qanday saqlanishi: Obyekt xotirada biror joyda saqlanadi (rasmning o'ng tomonida), `user` o'zgaruvchisi (chap tomonda) esa unga "havola" qiladi. +<<<<<<< HEAD `user` kabi obyekt o'zgaruvchisini obyektning manzili yozilgan qog'oz varaq deb tasavvur qilishimiz mumkin. +======= +We may think of an object variable, such as `user`, like a sheet of paper with the address of the object on it. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Obyekt bilan amallarni bajarganimizda, masalan `user.name` xossasini olganimizda, JavaScript dvigateli o'sha manzilda nima borligini ko'radi va haqiqiy obyektda operatsiyani bajaradi. @@ -100,10 +104,17 @@ alert(a == b); // false `obj1 > obj2` kabi solishtirishlar uchun yoki primitiv bilan solishtirish `obj == 5` uchun, obyektlar primitivlarga aylantiriladi. Obyekt aylantirishlari qanday ishlashini tez orada o'rganamiz, lekin rostini aytganda, bunday solishtirishlar juda kam kerak bo'ladi -- odatda ular dasturlash xatosi natijasida paydo bo'ladi. +<<<<<<< HEAD ````smart header="Const obyektlarni o'zgartirish mumkin" Obyektlarni havola sifatida saqlashning muhim yon ta'siri shundaki, `const` sifatida e'lon qilingan obyektni o'zgartirish *mumkin*. Masalan: +======= +````smart header="Const objects can be modified" +An important side effect of storing objects as references is that an object declared as `const` *can* be modified. + +For instance: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run const user = { @@ -124,12 +135,209 @@ Boshqacha qilib aytganda, `const user` faqat biz `user=...` ni butunlay o'rnatis Shuni aytish kerakki, agar biz haqiqatan ham doimiy obyekt xossalarini yaratishimiz kerak bo'lsa, bu ham mumkin, lekin butunlay boshqa usullardan foydalanib. Buni bobida eslatamiz. ```` +<<<<<<< HEAD ## Klonlash va birlashtirish, Object.assign [#cloning-and-merging-object-assign] +======= +## Cloning and merging, Object.assign [#cloning-and-merging-object-assign] + +So, copying an object variable creates one more reference to the same object. + +But what if we need to duplicate an object? + +We can create a new object and replicate the structure of the existing one, by iterating over its properties and copying them on the primitive level. + +Like this: + +```js run +let user = { + name: "John", + age: 30 +}; + +*!* +let clone = {}; // the new empty object + +// let's copy all user properties into it +for (let key in user) { + clone[key] = user[key]; +} +*/!* + +// now clone is a fully independent object with the same content +clone.name = "Pete"; // changed the data in it + +alert( user.name ); // still John in the original object +``` + +We can also use the method [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign). + +The syntax is: + +```js +Object.assign(dest, ...sources) +``` + +- The first argument `dest` is a target object. +- Further arguments is a list of source objects. + +It copies the properties of all source objects into the target `dest`, and then returns it as the result. + +For example, we have `user` object, let's add a couple of permissions to it: + +```js run +let user = { name: "John" }; + +let permissions1 = { canView: true }; +let permissions2 = { canEdit: true }; + +*!* +// copies all properties from permissions1 and permissions2 into user +Object.assign(user, permissions1, permissions2); +*/!* + +// now user = { name: "John", canView: true, canEdit: true } +alert(user.name); // John +alert(user.canView); // true +alert(user.canEdit); // true +``` + +If the copied property name already exists, it gets overwritten: + +```js run +let user = { name: "John" }; + +Object.assign(user, { name: "Pete" }); + +alert(user.name); // now user = { name: "Pete" } +``` + +We also can use `Object.assign` to perform a simple object cloning: + +```js run +let user = { + name: "John", + age: 30 +}; + +*!* +let clone = Object.assign({}, user); +*/!* + +alert(clone.name); // John +alert(clone.age); // 30 +``` + +Here it copies all properties of `user` into the empty object and returns it. + +There are also other methods of cloning an object, e.g. using the [spread syntax](info:rest-parameters-spread) `clone = {...user}`, covered later in the tutorial. + +## Nested cloning + +Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. + +Like this: +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +alert( user.sizes.height ); // 182 +``` + +Now it's not enough to copy `clone.sizes = user.sizes`, because `user.sizes` is an object, and will be copied by reference, so `clone` and `user` will share the same sizes: + +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +let clone = Object.assign({}, user); + +alert( user.sizes === clone.sizes ); // true, same object + +// user and clone share sizes +user.sizes.width = 60; // change a property from one place +alert(clone.sizes.width); // 60, get the result from the other one +``` + +To fix that and make `user` and `clone` truly separate objects, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning" or "structured cloning". There's [structuredClone](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) method that implements deep cloning. + + +### structuredClone + +The call `structuredClone(object)` clones the `object` with all nested properties. + +Here's how we can use it in our example: + +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +*!* +let clone = structuredClone(user); +*/!* + +alert( user.sizes === clone.sizes ); // false, different objects + +// user and clone are totally unrelated now +user.sizes.width = 60; // change a property from one place +alert(clone.sizes.width); // 50, not related +``` + +The `structuredClone` method can clone most data types, such as objects, arrays, primitive values. + +It also supports circular references, when an object property references the object itself (directly or via a chain or references). + +For instance: + +```js run +let user = {}; +// let's create a circular reference: +// user.me references the user itself +user.me = user; + +let clone = structuredClone(user); +alert(clone.me === clone); // true +``` + +As you can see, `clone.me` references the `clone`, not the `user`! So the circular reference was cloned correctly as well. + +Although, there are cases when `structuredClone` fails. + +For instance, when an object has a function property: + +```js run +// error +structuredClone({ + f: function() {} +}); +``` + +Function properties aren't supported. + +To handle such complex cases we may need to use a combination of cloning methods, write custom code or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com). + +## Summary +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shunday qilib, obyekt o'zgaruvchisini nusxalash bir xil obyektga yana bir havola yaratadi. Lekin agar bizga obyektni takrorlash kerak bo'lsa-chi? +<<<<<<< HEAD Biz yangi obyekt yaratishimiz va mavjud obyektning tuzilmasini takrorlashimiz mumkin, uning xossalari bo'ylab iteratsiya qilib va ularni primitiv darajada nusxalash orqali. Quyidagicha: @@ -323,3 +531,6 @@ Obyektlar havola bo'yicha tayinlanadi va nusxalanadi. Boshqacha qilib aytganda, Nusxalangan havolalar orqali barcha amallar (xossalar qo'shish/olib tashlash kabi) bir xil obyektda amalga oshiriladi. "Haqiqiy nusxa" (klon) yaratish uchun biz "sayoz nusxa" (ichma-ich obyektlar havola bo'yicha nusxalanadi) uchun `Object.assign` dan yoki "chuqur klonlash" funksiyasi `structuredClone` dan yoki [\_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) kabi maxsus klonlash implementatsiyasidan foydalanishimiz mumkin. +======= +To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function `structuredClone` or use a custom cloning implementation, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/04-object-basics/03-garbage-collection/article.md b/1-js/04-object-basics/03-garbage-collection/article.md index 12e381d3e..00a6892fe 100644 --- a/1-js/04-object-basics/03-garbage-collection/article.md +++ b/1-js/04-object-basics/03-garbage-collection/article.md @@ -75,7 +75,11 @@ Endi biz ham xuddi shunday qilsak: user = null; ``` +<<<<<<< HEAD ...Hozir ob'ektga `admin` global o'zgaruvchani orqali kirish mumkin, shuning uchun u xotirada. Agar biz `admin` ning qayta yozsak, u o'chirilishi mumkin. +======= +...Then the object is still reachable via `admin` global variable, so it must stay in memory. If we overwrite `admin` too, then it can be removed. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## O'zaro bog'langan ob'ektlar @@ -174,11 +178,19 @@ Birinchi qadam ildizlarni belgilaydi: ![](garbage-collection-2.svg) +<<<<<<< HEAD Keyin ularning havolalari belgilanadi: ![](garbage-collection-3.svg) ...Va ularning havolalari, iloji bo'lsa: +======= +Then we follow their references and mark referenced objects: + +![](garbage-collection-3.svg) + +...And continue to follow further references, while possible: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ![](garbage-collection-4.svg) @@ -188,13 +200,23 @@ Endi jarayonda tashrif buyurib bo'lmaydigan ob'ektlar erishish mumkin emas deb h Bu axlat yig'ish qanday ishlashining kontseptsiyasi. +<<<<<<< HEAD JavaScript interpretatori uni tezroq ishlashi va bajarilishiga ta'sir qilmasligi uchun ko'plab optimallashtirishlarni qo'llaydi. +======= +That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not introduce any delays into the code execution. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ba'zi optimallashtirishlar: +<<<<<<< HEAD - **Avlodlar to'plami (Generational collection)** - ob'ektlar ikkita to'plamga bo'linadi: "yangilari" va "eskilari". Ko'p ob'ektlar paydo bo'ladi, o'z ishlarini bajarishadi va tezda o'lishadi, ularni majburiy tarzda tozalash mumkin. Yetarlicha uzoq vaqt omon qolganlar, "eski" bo'lib, kamroq tekshiriladi. - **Qo'shimcha yig'ish (Incremental collection)** - agar ob'ektlar ko'p bo'lsa va biz birma-bir yurib, butun ob'ektni belgilashga harakat qilsak, bu biroz vaqt talab qilishi va bajarilishdagi kechikishlarni keltirib chiqarishi mumkin. Shunday qilib, interpretator axlat yig'ilishini qismlarga ajratishga harakat qiladi. Keyin qismlar birma-bir, alohida bajariladi. Buning uchun o'zgarishlarni kuzatib borish uchun ular o'rtasida qo'shimcha hisob olib borilishi kerak, ammo bizda aksariyat kechikishlar mavjud, ammo katta emas. - **Bo'sh vaqtni yig'ish (Idle-time collection)** - ishlashga ta'sirini kamaytirish uchun axlat yig'uvchi faqat protsessor uzilishlari vaqtida ishlashga harakat qiladi. +======= +- **Generational collection** -- objects are split into two sets: "new ones" and "old ones". In typical code, many objects have a short life span: they appear, do their job and die fast, so it makes sense to track new objects and clear the memory from them if that's the case. Those that survive for long enough, become "old" and are examined less often. +- **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine splits the whole set of existing objects into multiple parts. And then clear these parts one after another. There are many small garbage collections instead of a total one. That requires some extra bookkeeping between them to track changes, but we get many tiny delays instead of a big one. +- **Idle-time collection** -- the garbage collector tries to run only while the CPU is idle, to reduce the possible effect on the execution. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Axlat yig'ish algoritmlarini optimallashtirish va turli xil usullar mavjud. Lekin bu yerda ularni qanday ta'riflashni istasam ham, men bundan kechishim kerak, chunki turli JavaScript interpretatorlari turli usullar va sozlamalardan foydalanadilar. Va bundan ham muhimi, interpretatorlarning rivojlanishi bilan hamma narsa o'zgaradi, shuning uchun bu mavzuni oldindan ko'rib chiqish, haqiqiy ehtiyojsiz, ehtimol bunga loyiq emas. Agar, albatta, bu sof qiziqish masalasi bo'lmasa, unda quyidagi ba'zi havolalar siz uchun foydali bo'ladi. @@ -202,16 +224,30 @@ Axlat yig'ish algoritmlarini optimallashtirish va turli xil usullar mavjud. Leki Bilish kerak bo'lgan asosiy narsalar: +<<<<<<< HEAD - Axlat yig'ish avtomatik ravishda amalga oshiriladi. Biz uni majbuan oldini ololmaymiz. - Ob'ektlar erishuvchan bo'lganda xotirada saqlanadi. - Yo'naltiriladigan havola (ildizdan) erishish bilan bir xil emas: o'zaro bog'langan ob'ektlar to'plami umuman olganda yetib bo'lmaydigan bo'lib qolishi mumkin. +======= +- Garbage collection is performed automatically. We cannot force or prevent it. +- Objects are retained in memory while they are reachable. +- Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole, as we've seen in the example above. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Zamonaviy interpretatorlar axlat yig'ishning zamonaviy algoritmlarini amalga oshirmoqdalar. Umumiy kitob "The Garbage Collection Handbook: The Art of Automatic Memory Management" (R. Jons va boshqalar) ularning ayrimlarini qamrab oladi. +<<<<<<< HEAD Agar siz past darajadagi dasturlarni yaxshi bilsangiz, V8 axlatni yig'uvchi haqida batafsil ma'lumot [V8 tur: Axlat yig'ish](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection) maqolasida keltirilgan. Bundan tashqari, [V8 interpretatorning blogida](http://v8project.blogspot.com/) vaqti bilan xotira boshqaruvidagi o'zgarishlar haqida maqolalar chop etiladi. Albatta, axlat yig'ishni o'rganish uchun siz V8 interpretatori ichida qanday ishlashini tushunishingiz kerak. Buni V8-ni ishlab chiqqan muhandislardan biri [Vyacheslav Egorov](http://mrale.ph) blogida o'qishingiz mumkin. Men "V8" haqida gapiryapman, chunki u internetdagi maqolalar bilan eng yaxshi yoritilgan. Boshqa interpretatorda ko'plab yondashuvlar o'xshash, ammo axlat yig'ish ko'p jihatda farq qiladi. Interpretatorni chuqur bilish, past darajadagi optimallashtirish kerak bo'lganda yaxshi bo'ladi. Buni til bilan tanishganingizdan keyin keyingi qadam sifatida rejalashtirish oqilona bo'ladi. +======= +If you are familiar with low-level programming, more detailed information about V8's garbage collector is in the article [A tour of V8: Garbage Collection](https://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection). + +The [V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn more about garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](https://mrale.ph) who worked as one of the V8 engineers. I'm saying: "V8", because it is best covered by articles on the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects. + +In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md index fdb220954..199f0d3cb 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md @@ -6,9 +6,15 @@ muhimlik: 5 Uch usul bilan `calculator` obyektini yarating: +<<<<<<< HEAD - `read()` ikkita qiymatni so'raydi va ularni obyekt xususiyatlari sifatida saqlaydi. - `sum()` saqlangan qiymatlar yig'indisini qaytaradi. - `mul()` saqlangan qiymatlarni ko'paytiradi va natijani qaytaradi. +======= +- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively. +- `sum()` returns the sum of saved values. +- `mul()` multiplies saved values and returns the result. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let calculator = { diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js index 5b55929fa..d9b3c10dc 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js @@ -10,5 +10,11 @@ let ladder = { }, showStep: function () { alert(this.step); +<<<<<<< HEAD }, }; +======= + return this; + } +}; +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js index 9fc0bd7d7..61f5fda86 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js @@ -32,7 +32,19 @@ describe("Ladder", function () { assert.equal(ladder.down().up().up().up().step, 2); }); +<<<<<<< HEAD after(function () { +======= + it('showStep() should return this', function() { + assert.equal(ladder.showStep(), ladder); + }); + + it('up().up().down().showStep().down().showStep()', function () { + assert.equal(ladder.up().up().down().showStep().down().showStep().step, 0) + }); + + after(function() { +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ladder.step = 0; alert.restore(); }); diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index 9e49710d3..42b88a039 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -23,11 +23,21 @@ let ladder = { } }; -ladder.up().up().down().up().down().showStep(); // 1 +ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0 ``` Biz har bir satr uchun bitta chaqiruv yozishimiz mumkin. Uzoq zanjirlar uchun o'qilishni oson qiladi: ```js +<<<<<<< HEAD ladder.up().up().down().up().down().showStep(); // 1 +======= +ladder + .up() + .up() + .down() + .showStep() // 1 + .down() + .showStep(); // 0 +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md index 63c998bb4..9459a759e 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md @@ -4,7 +4,11 @@ muhimlik: 2 # Zanjirlash +<<<<<<< HEAD Yuqoriga va pastga tushishga imkon beradigan `ladder` obyekti mavjud: +======= +There's a `ladder` object that allows you to go up and down: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let ladder = { @@ -22,19 +26,33 @@ let ladder = { }; ``` +<<<<<<< HEAD Endi, biz ketma-ket bir nechta chaqiruvlarni amalga oshirishimiz kerak bo'lsa, buni quyidagicha qilishimiz mumkin: +======= +Now, if we need to make several calls in sequence, we can do it like this: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js ladder.up(); ladder.up(); ladder.down(); ladder.showStep(); // 1 +ladder.down(); +ladder.showStep(); // 0 ``` +<<<<<<< HEAD Chaqiruvlarni zanjirlash uchun `up`, `down` va `showStep` kodlarini o'zgartiring: +======= +Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js -ladder.up().up().down().showStep(); // 1 +ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0 ``` +<<<<<<< HEAD Bunday yondashuv JavaScript kutubxonalarida keng qo'llaniladi. +======= +Such an approach is widely used across JavaScript libraries. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 3473d5b30..277374a1b 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -51,7 +51,7 @@ let user = { // birinchi, e'lon qiling function sayHi() { alert("Hello!"); -}; +} // keyin usul sifatida qo'shing user.sayHi = sayHi; @@ -91,7 +91,11 @@ let user = { Ko'rsatilganidek, biz `"function"` ni qoldirib, faqat `sayHi()` yozishimiz mumkin. +<<<<<<< HEAD Rostini aytsam, yozuvlar bir-biriga to'liq o'xshash emas. Obyektni meros qilib olish bilan bog'liq nozik farqlar mavjud (keyinroq ko'rib chiqiladi), ammo hozircha ularning ahamiyati yo'q. Deyarli barcha hollarda qisqa sintaksisga ustunlik beriladi. +======= +To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases, the shorter syntax is preferred. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## "this" usullarda diff --git a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md index 276a6d39d..614297b24 100644 --- a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md +++ b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md @@ -4,14 +4,18 @@ muhimlik: 2 # Ikki funktsiya - bitta obyekt +<<<<<<< HEAD `A` va `B` funktsiyalarini `new A()==new B()` kabi yaratish mumkinmi? +======= +Is it possible to create functions `A` and `B` so that `new A() == new B()`? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js no-beautify function A() { ... } function B() { ... } -let a = new A; -let b = new B; +let a = new A(); +let b = new B(); alert( a == b ); // true ``` diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md index 7a5ea87df..656f7d0b8 100644 --- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md +++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md @@ -6,9 +6,15 @@ muhimlik: 5 Obyektlarni 3 usul bilan yaratadigan "Kalkulyator" konstruktor funktsiyasini yarating: +<<<<<<< HEAD - `read()` `prompt` yordamida ikkita qiymatni so'raydi va ularni obyekt xususiyatlarida eslab qoladi. - `sum()` ushbu xususiyatlarning yig'indisini qaytaradi. - `mul()` ushbu xususiyatlarning ko'paytish mahsulotini qaytaradi. +======= +- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively. +- `sum()` returns the sum of these properties. +- `mul()` returns the multiplication product of these properties. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan: diff --git a/1-js/04-object-basics/06-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md index 9aca5f02a..804bf07c2 100644 --- a/1-js/04-object-basics/06-constructor-new/article.md +++ b/1-js/04-object-basics/06-constructor-new/article.md @@ -1,6 +1,10 @@ # Konstruktor, operator "new" +<<<<<<< HEAD Oddiy `{...}` sintaksisi bitta obyektni yaratishga imkon beradi. Ammo ko'pincha biz shunga o'xshash ko'plab obyektlarni yaratishimiz kerak, masalan, bir nechta foydalanuvchi yoki menyu elementlari va boshqalar. +======= +The regular `{...}` syntax allows us to create one object. But often we need to create many similar objects, like multiple users or menu items and so on. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Buni konstruktor funktsiyalari va `"new"` operator yordamida amalga oshirish mumkin. @@ -168,8 +172,13 @@ alert(new SmallUser().name); // Elbek Odatda konstruktorlarda `return` ifodasi mavjud emas. Ushbu blokda tilni o'rganishdagi bo'shliqlarni qoldirmaslik uchun obyektni qaytarish bilan bog'liq alohida xatti-harakatlar haqida so'z yuritdik. +<<<<<<< HEAD ````smart header="Qavslar chushirib qo'yish" Aytgancha, agar bizda argument bo'lmasa, qavslarni `new` dan keyin olib tashlashimiz mumkin: +======= +````smart header="Omitting parentheses" +By the way, we can omit parentheses after `new`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let user = new User; // <-- qavslar yo'q diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md index d3e428adf..4781fa5c2 100644 --- a/1-js/04-object-basics/07-optional-chaining/article.md +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -24,14 +24,22 @@ Bu kutilgan natija. JavaScript shunday ishlaydi. `user.address` `undefined` bo'l Ko'plab amaliy hollarda biz bu yerda xato o'rniga `undefined` olishni afzal ko'ramiz ("ko'cha yo'q" ma'nosida). +<<<<<<< HEAD ...Va yana bir misol. Veb-dasturlashda biz `document.querySelector('.elem')` kabi maxsus usul chaqiruvi orqali veb-sahifa elementiga mos keladigan obyektni olishimiz mumkin va bunday element bo'lmasa `null` qaytaradi. +======= +...and another example. In Web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run // document.querySelector('.elem') element bo'lmasa null let html = document.querySelector(".elem").innerHTML; // null bo'lsa xato ``` +<<<<<<< HEAD Yana, agar element mavjud bo'lmasa, biz `null` ning `.innerHTML` ga kirishda xato olamiz. Va ba'zi hollarda, element yo'qligi normal bo'lganda, biz xatolardan qochmoqchimiz va shunchaki natija sifatida `html = null` ni qabul qilmoqchimiz. +======= +Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` property of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Buni qanday qilishimiz mumkin? @@ -43,11 +51,27 @@ let user = {}; alert(user.address ? user.address.street : undefined); ``` +<<<<<<< HEAD Bu ishlaydi, xato yo'q... Lekin juda nafis emas. Ko'rib turganingizdek, `"user.address"` kodda ikki marta uchraydi. Chuqurroq joylashtirilgan xossalar uchun bu muammoga aylanadi, chunki ko'proq takrorlash talab qilinadi. Masalan, `user.address.street.name` ni olishga harakat qilaylik. Biz ham `user.address` ni ham `user.address.street` ni tekshirishimiz kerak: +======= +It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code. + +Here's how the same would look for `document.querySelector`: + +```js run +let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null; +``` + +We can see that the element search `document.querySelector('.elem')` is actually called twice here. Not good. + +For more deeply nested properties, it becomes even uglier, as more repetitions are required. + +E.g. let's get `user.address.street.name` in a similar fashion. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let user = {}; // foydalanuvchida manzil yo'q @@ -59,7 +83,11 @@ alert( Bu dahshatli, kimdir bunday kodni tushunishda muammo bo'lishi mumkin. +<<<<<<< HEAD Bunga qaramang, uni `&&` operatori yordamida yozishning yaxshi usuli bor: +======= +There's a little better way to write it, using the `&&` operator: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let user = {}; // foydalanuvchida manzil yo'q @@ -94,7 +122,17 @@ alert(user?.address?.street); // undefined (xato yo'q) Kod qisqa va toza, umuman takrorlash yo'q. +<<<<<<< HEAD `user?.address` bilan manzilni o'qish `user` obyekti mavjud bo'lmasa ham ishlaydi: +======= +Here's an example with `document.querySelector`: + +```js run +let html = document.querySelector('.elem')?.innerHTML; // will be undefined, if there's no element +``` + +Reading the address with `user?.address` works even if `user` object doesn't exist: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let user = null; @@ -110,9 +148,15 @@ Masalan, `user?.address.street.name` da `?.` `user` ning xavfsiz ravishda `null/ ```warn header="Ixtiyoriy zanjirdan ortiqcha foydalanmang" Biz `?.` ni faqat biror narsa mavjud bo'lmasligi normal bo'lgan joylarda ishlatishimiz kerak. +<<<<<<< HEAD Masalan, agar bizning kodlash mantiqimizga ko'ra `user` obyekti mavjud bo'lishi kerak, lekin `address` ixtiyoriy bo'lsa, biz `user.address?.street` yozishimiz kerak, `user?.address?.street` emas. Shunday qilib, agar `user` xato tufayli undefined bo'lib qolsa, biz bu haqda dasturlash xatosini ko'ramiz va uni tuzatamiz. Aks holda, kodlash xatolari kerakli bo'lmagan joyda jim qolishi va disk raskadka qilish qiyinlashishi mumkin. +======= +For example, if according to our code logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`. + +Then, if `user` happens to be undefined, we'll see a programming error about it and fix it. Otherwise, if we overuse `?.`, coding errors can be silenced where not appropriate, and become more difficult to debug. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ````warn header="`?.`dan oldingi o'zgaruvchi e'lon qilingan bo'lishi kerak" @@ -127,7 +171,11 @@ O'zgaruvchi e'lon qilingan bo'lishi kerak (masalan, `let/const/var user` yoki fu ````` +<<<<<<< HEAD ## Qisqa tutashuv +======= +So, if there are any further function calls or operations to the right of `?.`, they won't be made. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ilgari aytilganidek, chap qism mavjud bo'lmasa `?.` darhol to'xtaydi ("qisqa tutashadi"). @@ -139,7 +187,11 @@ Masalan: let user = null; let x = 0; +<<<<<<< HEAD user?.sayHi(x++); // "sayHi" yo'q, shuning uchun bajarilish x++ ga yetmaydi +======= +user?.sayHi(x++); // no "user", so the execution doesn't reach sayHi call and x++ +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 alert(x); // 0, qiymat oshirilmadi ``` @@ -166,6 +218,7 @@ userAdmin.admin?.(); // Men adminman */!* *!* +<<<<<<< HEAD userGuest.admin?.(); // hech narsa (bunday usul yo'q) */!* ``` @@ -173,6 +226,15 @@ userGuest.admin?.(); // hech narsa (bunday usul yo'q) Bu yerda ikkala qatorda ham avval nuqtadan foydalanib (`userAdmin.admin`) `admin` xossasini olamiz, chunki user obyekti mavjud deb taxmin qilamiz, shuning uchun undan o'qish xavfsiz. Keyin `?.()` chap qismni tekshiradi: agar admin funksiyasi mavjud bo'lsa, u ishga tushadi (`userAdmin` uchun shunday). Aks holda (`userGuest` uchun) baholash xatosiz to'xtaydi. +======= +userGuest.admin?.(); // nothing happens (no such method) +*/!* +``` + +Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the `user` object exists, so it's safe read from it. + +Then `?.()` checks the left part: if the `admin` function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `?.[]` sintaksisi ham ishlaydi, agar biz nuqta `.` o'rniga xossalarga kirish uchun qavslar `[]` dan foydalanmoqchi bo'lsak. Oldingi hollarga o'xshab, u mavjud bo'lmasligi mumkin bo'lgan obyektdan xavfsiz ravishda xossa o'qishga imkon beradi. @@ -195,19 +257,32 @@ Shuningdek, biz `?.` ni `delete` bilan ishlatishimiz mumkin: delete user?.name; // agar user mavjud bo'lsa user.name ni o'chirish ``` +<<<<<<< HEAD ````warn header="Biz `?.` ni xavfsiz o'qish va o'chirish uchun ishlatishimiz mumkin, lekin yozish uchun emas" Ixtiyoriy zanjir `?.` tayinlashning chap tomonida foydalanilmaydi. +======= +````warn header="We can use `?.` for safe reading and deleting, but not writing" +The optional chaining `?.` has no use on the left side of an assignment. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan: ```js run let user = null; +<<<<<<< HEAD user?.name = "John"; // Xato, ishlamaydi // chunki u undefined = "John" ga baholanadi ``` Bu shunchaki aqlli emas. ````` +======= +user?.name = "John"; // Error, doesn't work +// because it evaluates to: undefined = "John" +``` + +```` +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Xulosa @@ -221,4 +296,8 @@ Ko'rib turganingizdek, ularning barchasi oddiy va foydalanish oson. `?.` chap qi `?.` zanjiri ichma-ich xossalarga xavfsiz kirish imkonini beradi. +<<<<<<< HEAD Shunga qaramay, biz `?.` ni ehtiyotkorlik bilan, faqat chap qismning mavjud bo'lmasligi qabul qilinadigan joylarda qo'llashimiz kerak. Shunda u bizdan dasturlash xatolarini yashirmaydi, agar ular sodir bo'lsa. +======= +Still, we should apply `?.` carefully, only where it's acceptable, according to our code logic, that the left part doesn't exist. So that it won't hide programming errors from us, if they occur. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/04-object-basics/08-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md index 7f8116d5e..18496485f 100644 --- a/1-js/04-object-basics/08-symbol/article.md +++ b/1-js/04-object-basics/08-symbol/article.md @@ -2,27 +2,51 @@ Spetsifikatsiya bo'yicha obyekt xususiyatining kalitlari matn turi yoki belgi turi bo'lishi mumkin. Raqamlar emas, mantiqiy emas, faqat matn yoki belgilar, bu ikki tur bo'lishi mumkin. +<<<<<<< HEAD Hozirgacha biz faqat matnlarni ko'rib chiqamiz. Keling, belgilar bizga beradigan afzalliklarni ko'rib chiqaylik. ## Belgilar +======= +By specification, only two primitive types may serve as object property keys: + +- string type, or +- symbol type. + +Otherwise, if one uses another type, such as number, it's autoconverted to string. So that `obj[1]` is the same as `obj["1"]`, and `obj[true]` is the same as `obj["true"]`. + +Until now we've been using only strings. + +Now let's explore symbols, see what they can do for us. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 "Symbol" qiymati noyob identifikatorni ifodalaydi. Ushbu turdagi qiymatni `Symbol()` yordamida yaratish mumkin: ```js +<<<<<<< HEAD // id bu yangi belgi let id = Symbol(); ``` Shuningdek, biz belgiga tavsif bera olamiz (belgi nomi ham deyiladi), bu asosan koddagi hatoliklarni tuzatish uchun foydalidir: +======= +let id = Symbol(); +``` + +Upon creation, we can give symbols a description (also called a symbol name), mostly useful for debugging purposes: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run // id bu "id" tavsifiga ega bo'lgan belgidir let id = Symbol("id"); ``` +<<<<<<< HEAD Belgilar noyob bo'lishi kafolatlanadi. Agar biz bir xil tavsifga ega bo'lgan ko'plab belgilarni yaratadigan bo'lsak ham, ular har xil qiymatlardir. Tavsif shunchaki hech narsaga ta'sir qilmaydigan yorliq. +======= +Symbols are guaranteed to be unique. Even if we create many symbols with exactly the same description, they are different values. The description is just a label that doesn't affect anything. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, mana bir xil tavsifga ega ikkita belgi -- ular teng emas: @@ -37,8 +61,15 @@ alert(id1 == id2); // false Agar siz Ruby yoki boshqa biron bir "symbol" ga ega bo'lgan boshqa tilni bilsangiz, iltimos, adashmang. JavaScript-da belgilar boshqacha. +<<<<<<< HEAD ````warn header="Belgilar avtomatik ravishda matnga aylantirilmaydi" JavaScript-dagi aksariyat qiymatlar matnga aylantirishni qo'llab-quvvatlaydi. Masalan, biz deyarli har qanday qiymatni `alert` ya'ni ekranga chiqazishimiz mumkin va u ishlaydi. Belgilar alohida ahamiyatga ega. Ular avtomatik konvertatsiya qilmaydi. +======= +So, to summarize, a symbol is a "primitive unique value" with an optional description. Let's see where we can use them. + +````warn header="Symbols don't auto-convert to a string" +Most values in JavaScript support implicit conversion to a string. For instance, we can `alert` almost any value, and it will work. Symbols are special. They don't auto-convert. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, ushbu `alert` xatolikni ko'rsatadi: @@ -52,7 +83,12 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not occasionally convert one into another. Bu tartibsizliklardan "til himoyasi", chunki matnlar va belgilar bir-biridan tubdan farq qiladi vatasodifan boshqasiga konvertatsiya qilinmasi kerak. +<<<<<<< HEAD Agar biz chindan ham belgini ko'rsatishni istasak, unda `.toString()` ni chaqirishimiz kerak, masalan: +======= +If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let id = Symbol("id"); *!* @@ -60,7 +96,12 @@ alert(id.toString()); // Symbol(id), endi u ishlaydi */!* ``` +<<<<<<< HEAD Yoki faqat tavsifni olish uchun `symbol.description` xususiyatini ishlatamiz: +======= +Or get `symbol.description` property to show the description only: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let id = Symbol("id"); *!* @@ -72,7 +113,12 @@ alert(id.description); // id ## "Yashirin" xususiyatlar +<<<<<<< HEAD Belgilar bizga obyektning "yashirin" xususiyatlarini yaratishga imkon beradi, chunki kodning boshqa hech bir qismi tasodifan kira olmaydi va qayta yozib bo'lmaydi. +======= + +Symbols allow us to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, ёuser` obyekti uchun "identifikator" ni saqlamoqchi bo'lsak, buning uchun kalit sifatida belgidan foydalanishimiz mumkin: @@ -90,9 +136,15 @@ alert(user[id]); // biz kalit sifatida belgidan foydalangan holda ma'lumotlarga `"id"` ning o'rniga `Symbol("id")` dan ishlatishning foydasi nimada? +<<<<<<< HEAD Buni ko'rish uchun misolni biroz chuqurroq qilaylik. Tasavvur qiling, boshqa skript o'z maqsadi uchun `user` ichida o'z "id" xususiyatiga ega bo'lishni xohlaydi. Bu boshqa JavaScript kutubxonasi bo'lishi mumkin, shuning uchun skriptlar bir-biridan umuman bexabar. +======= +As `user` objects belong to another codebase, it's unsafe to add fields to them, since we might affect pre-defined behavior in that other codebase. However, symbols cannot be accessed accidentally. The third-party code won't be aware of newly defined symbols, so it's safe to add symbols to the `user` objects. + +Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Keyin ushbu skript o'z `Symbol("id")` ni yaratishi mumkin, masalan: @@ -156,11 +208,19 @@ let user = { for (let key in user) alert(key); // name, age (belgilar yo'q) */!* +<<<<<<< HEAD // to'g'ridan-to'g'ri murojaat belgisi ishlaydi alert( "Direct: " + user[id] ); ``` Bu umumiy "yashirish" tushunchasining bir qismi. Agar boshqa skript yoki kutubxona bizning obyektimizga o'girilsa, u kutilmaganda belgi xususiyatga kira olmaydi. +======= +// the direct access by the symbol works +alert( "Direct: " + user[id] ); // Direct: 123 +``` + +[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Aksincha, [Object.assign](mdn:js/Object/assigned) ham matn, ham belgi xususiyatlarini ko'chiradi: @@ -223,12 +283,20 @@ Registr ichidagi belgilar _global belgilar_ deb nomlanadi. Agar biz keng ko'laml ```smart header="Bu Ruby-ga o'xshaydi" Ruby singari ba'zi dasturlash tillarida bitta nom uchun bitta belgi mavjud. +<<<<<<< HEAD JavaScript-da, biz ko'rib turganimizdek, bu bayonot faqat global belgilar uchun to'g'ri. +======= +In JavaScript, as we can see, that's true for global symbols. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ### Symbol.keyFor +<<<<<<< HEAD Global belgilar uchun nafaqat `Symbol.for(key)` belgini nomini qaytaradi, balki teskari chaqirish mavjud: `Symbol.keyFor(sym)`, bu teskari: nomni global belgi bilan qaytaradi. +======= +We have seen that for global symbols, `Symbol.for(key)` returns a symbol by name. To do the opposite -- return a name by global symbol -- we can use: `Symbol.keyFor(sym)`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan: @@ -244,7 +312,13 @@ alert(Symbol.keyFor(sym2)); // id `Symbol.keyFor` belgi uchun kalitni izlash uchun global belgilar registridan foydalanadi. Shunday qilib, u global bo'lmagan belgilar uchun ishlamaydi. Agar belgi global bo'lmasa, uni topa olmaydi va `undefined` ni qaytaradi. +<<<<<<< HEAD Masalan: +======= +That said, all symbols have the `description` property. + +For instance: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert(Symbol.keyFor(Symbol.for("name"))); // name, global belgi @@ -278,11 +352,21 @@ Belgilar bir xil nomga ega bo'lsa ham, har doim har xil qiymatga ega. Agar biz b Belgilar ikkita asosiy foydalanish holatiga ega: +<<<<<<< HEAD 1. "Yashirin" obyekt xususiyatlari. Agar biz boshqa skriptga yoki kutubxonaga "tegishli" bo'lgan obyektga xususiyat qo'shmoqchi bo'lsak, biz belgi yaratib, uni xususiyat kaliti sifatida ishlatishimiz mumkin. Belgi xususiyati `for..in` da ko'rinmaydi, shuning uchun u kutilmaganda ro'yxatga olinmaydi. Bundan tashqari, unga to'g'ridan-to'g'ri kirish imkoni bo'lmaydi, chunki boshqa skriptda bizning belgimiz yo'q, shuning uchun u kutilmaganda uning harakatlariga aralashmaydi. +======= +1. "Hidden" object properties. + + If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be accidentally processed together with other properties. Also it won't be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shunday qilib, biz o'zimizga kerak bo'lgan obyektlarni "yashirincha" bekita olamiz, ammo boshqalar ko'rmasligi uchun, belgi xususiyatlaridan foydalanadi. 2. JavaScript tomonidan ishlatiladigan `Symbol.*` kabi tizimining ko'pgina belgilari mavjud. Biz ulardan ichki o'rnatilgan xatti-harakatlarni o'zgartirish uchun foydalanishimiz mumkin. Masalan, keyinchalik o'quv qo'llanmada biz `Symbol.toPrimitive` [obyektdan ibtidoiy konvertatsiya](info:object-toprimitive) va boshqalarni o'rnatish uchun `Symbol.iterator` dan foydalanamiz [iterables](info:iterable). +<<<<<<< HEAD Texnik jihatdan belgilar 100% yashirin emas. Barcha belgilarni olishimizga imkon beradigan o'rnatilgan [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) usuli mavjud. Shuningdek, [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) deb nomlangan usul mavjud, bu obyektning _barcha_ kalitlarni, shu jumladan belgi kalitlarni qaytaradi. Shunday qilib, ular haqiqatan ham yashirin emas. Ammo aksariyat kutubxonalar, o'rnatilgan usullar va sintaksis tuzilmalari umumiy kelishuvga amal qilishadi. Yuqorida aytib o'tilgan usullarni aniq chaqirgan kishi, ehtimol, nima qilayotganini yaxshi tushunadi. +======= +Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. But most libraries, built-in functions and syntax constructs don't use these methods. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md new file mode 100644 index 000000000..fa68da583 --- /dev/null +++ b/1-js/04-object-basics/09-object-toprimitive/article.md @@ -0,0 +1,280 @@ + +# Object to primitive conversion + +What happens when objects are added `obj1 + obj2`, subtracted `obj1 - obj2` or printed using `alert(obj)`? + +JavaScript doesn't allow you to customize how operators work on objects. Unlike some other programming languages, such as Ruby or C++, we can't implement a special object method to handle addition (or other operators). + +In case of such operations, objects are auto-converted to primitives, and then the operation is carried out over these primitives and results in a primitive value. + +That's an important limitation: the result of `obj1 + obj2` (or another math operation) can't be another object! + +E.g. we can't make objects representing vectors or matrices (or achievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board". + +So, because we can't technically do much here, there's no maths with objects in real projects. When it happens, with rare exceptions, it's because of a coding mistake. + +In this chapter we'll cover how an object converts to primitive and how to customize it. + +We have two purposes: + +1. It will allow us to understand what's going on in case of coding mistakes, when such an operation happened accidentally. +2. There are exceptions, where such operations are possible and look good. E.g. subtracting or comparing dates (`Date` objects). We'll come across them later. + +## Conversion rules + +In the chapter we've seen the rules for numeric, string and boolean conversions of primitives. But we left a gap for objects. Now, as we know about methods and symbols it becomes possible to fill it. + +1. There's no conversion to boolean. All objects are `true` in a boolean context, as simple as that. There exist only numeric and string conversions. +2. The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, `Date` objects (to be covered in the chapter ) can be subtracted, and the result of `date1 - date2` is the time difference between two dates. +3. As for the string conversion -- it usually happens when we output an object with `alert(obj)` and in similar contexts. + +We can implement string and numeric conversion by ourselves, using special object methods. + +Now let's get into technical details, because it's the only way to cover the topic in-depth. + +## Hints + +How does JavaScript decide which conversion to apply? + +There are three variants of type conversion, that happen in various situations. They're called "hints", as described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive): + +`"string"` +: For an object-to-string conversion, when we're doing an operation on an object that expects a string, like `alert`: + + ```js + // output + alert(obj); + + // using object as a property key + anotherObj[obj] = 123; + ``` + +`"number"` +: For an object-to-number conversion, like when we're doing maths: + + ```js + // explicit conversion + let num = Number(obj); + + // maths (except binary plus) + let n = +obj; // unary plus + let delta = date1 - date2; + + // less/greater comparison + let greater = user1 > user2; + ``` + + Most built-in mathematical functions also include such conversion. + +`"default"` +: Occurs in rare cases when the operator is "not sure" what type to expect. + + For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them). So if a binary plus gets an object as an argument, it uses the `"default"` hint to convert it. + + Also, if an object is compared using `==` with a string, number or a symbol, it's also unclear which conversion should be done, so the `"default"` hint is used. + + ```js + // binary plus uses the "default" hint + let total = obj1 + obj2; + + // obj == number uses the "default" hint + if (user == 1) { ... }; + ``` + + The greater and less comparison operators, such as `<` `>`, can work with both strings and numbers too. Still, they use the `"number"` hint, not `"default"`. That's for historical reasons. + +In practice though, things are a bit simpler. + +All built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And we probably should do the same. + +Still, it's important to know about all 3 hints, soon we'll see why. + +**To do the conversion, JavaScript tries to find and call three object methods:** + +1. Call `obj[Symbol.toPrimitive](hint)` - the method with the symbolic key `Symbol.toPrimitive` (system symbol), if such method exists, +2. Otherwise if hint is `"string"` + - try calling `obj.toString()` or `obj.valueOf()`, whatever exists. +3. Otherwise if hint is `"number"` or `"default"` + - try calling `obj.valueOf()` or `obj.toString()`, whatever exists. + +## Symbol.toPrimitive + +Let's start from the first method. There's a built-in symbol named `Symbol.toPrimitive` that should be used to name the conversion method, like this: + +```js +obj[Symbol.toPrimitive] = function(hint) { + // here goes the code to convert this object to a primitive + // it must return a primitive value + // hint = one of "string", "number", "default" +}; +``` + +If the method `Symbol.toPrimitive` exists, it's used for all hints, and no more methods are needed. + +For instance, here `user` object implements it: + +```js run +let user = { + name: "John", + money: 1000, + + [Symbol.toPrimitive](hint) { + alert(`hint: ${hint}`); + return hint == "string" ? `{name: "${this.name}"}` : this.money; + } +}; + +// conversions demo: +alert(user); // hint: string -> {name: "John"} +alert(+user); // hint: number -> 1000 +alert(user + 500); // hint: default -> 1500 +``` + +As we can see from the code, `user` becomes a self-descriptive string or a money amount, depending on the conversion. The single method `user[Symbol.toPrimitive]` handles all conversion cases. + +## toString/valueOf + +If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`: + +- For the `"string"` hint: call `toString` method, and if it doesn't exist or if it returns an object instead of a primitive value, then call `valueOf` (so `toString` has the priority for string conversions). +- For other hints: call `valueOf`, and if it doesn't exist or if it returns an object instead of a primitive value, then call `toString` (so `valueOf` has the priority for maths). + +Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion. + +These methods must return a primitive value. If `toString` or `valueOf` returns an object, then it's ignored (same as if there were no method). + +By default, a plain object has following `toString` and `valueOf` methods: + +- The `toString` method returns a string `"[object Object]"`. +- The `valueOf` method returns the object itself. + +Here's the demo: + +```js run +let user = {name: "John"}; + +alert(user); // [object Object] +alert(user.valueOf() === user); // true +``` + +So if we try to use an object as a string, like in an `alert` or so, then by default we see `[object Object]`. + +The default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist. + +Let's implement these methods to customize the conversion. + +For instance, here `user` does the same as above using a combination of `toString` and `valueOf` instead of `Symbol.toPrimitive`: + +```js run +let user = { + name: "John", + money: 1000, + + // for hint="string" + toString() { + return `{name: "${this.name}"}`; + }, + + // for hint="number" or "default" + valueOf() { + return this.money; + } + +}; + +alert(user); // toString -> {name: "John"} +alert(+user); // valueOf -> 1000 +alert(user + 500); // valueOf -> 1500 +``` + +As we can see, the behavior is the same as the previous example with `Symbol.toPrimitive`. + +Often we want a single "catch-all" place to handle all primitive conversions. In this case, we can implement `toString` only, like this: + +```js run +let user = { + name: "John", + + toString() { + return this.name; + } +}; + +alert(user); // toString -> John +alert(user + 500); // toString -> John500 +``` + +In the absence of `Symbol.toPrimitive` and `valueOf`, `toString` will handle all primitive conversions. + +### A conversion can return any primitive type + +The important thing to know about all primitive-conversion methods is that they do not necessarily return the "hinted" primitive. + +There is no control whether `toString` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for the hint `"number"`. + +The only mandatory thing: these methods must return a primitive, not an object. + +```smart header="Historical notes" +For historical reasons, if `toString` or `valueOf` returns an object, there's no error, but such value is ignored (like if the method didn't exist). That's because in ancient times there was no good "error" concept in JavaScript. + +In contrast, `Symbol.toPrimitive` is stricter, it *must* return a primitive, otherwise there will be an error. +``` + +## Further conversions + +As we know already, many operators and functions perform type conversions, e.g. multiplication `*` converts operands to numbers. + +If we pass an object as an argument, then there are two stages of calculations: +1. The object is converted to a primitive (using the rules described above). +2. If necessary for further calculations, the resulting primitive is also converted. + +For instance: + +```js run +let obj = { + // toString handles all conversions in the absence of other methods + toString() { + return "2"; + } +}; + +alert(obj * 2); // 4, object converted to primitive "2", then multiplication made it a number +``` + +1. The multiplication `obj * 2` first converts the object to primitive (that's a string `"2"`). +2. Then `"2" * 2` becomes `2 * 2` (the string is converted to number). + +Binary plus will concatenate strings in the same situation, as it gladly accepts a string: + +```js run +let obj = { + toString() { + return "2"; + } +}; + +alert(obj + 2); // "22" ("2" + 2), conversion to primitive returned a string => concatenation +``` + +## Summary + +The object-to-primitive conversion is called automatically by many built-in functions and operators that expect a primitive as a value. + +There are 3 types (hints) of it: +- `"string"` (for `alert` and other operations that need a string) +- `"number"` (for maths) +- `"default"` (few operators, usually objects implement it the same way as `"number"`) + +The specification describes explicitly which operator uses which hint. + +The conversion algorithm is: + +1. Call `obj[Symbol.toPrimitive](hint)` if the method exists, +2. Otherwise if hint is `"string"` + - try calling `obj.toString()` or `obj.valueOf()`, whatever exists. +3. Otherwise if hint is `"number"` or `"default"` + - try calling `obj.valueOf()` or `obj.toString()`, whatever exists. + +All these methods must return a primitive to work (if defined). + +In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes. diff --git a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md index 42f094f5e..842795ac2 100644 --- a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md +++ b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md @@ -14,4 +14,8 @@ str.test = 5; alert(str.test); ``` +<<<<<<< HEAD Sizningcha, u qanday ishlaydi? Nima ko'rsatiladi? +======= +What do you think, will it work? What will be shown? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md index c69e6baa9..6d73adcdb 100644 --- a/1-js/05-data-types/01-primitives-methods/article.md +++ b/1-js/05-data-types/01-primitives-methods/article.md @@ -41,8 +41,13 @@ Obyektlar ibtidoiylarga qaraganda "og'irroq". Ular ichki texnikani qo'llab-quvva JavaScript-ni yaratuvchisi duch kelgan paradoks: +<<<<<<< HEAD - Matn yoki raqam kabi ibtidoiylar bilan ishlashni istagan juda ko'p narsa bor. Agar ular bilan usullar orqali ishlashimiz mumkin bo'lsa, bu ajoyib bo'lar edi. - Ibtidoiylar imkon qadar tez va yengil bo'lishi kerak. +======= +- There are many things one would want to do with a primitive, like a string or a number. It would be great to access them using methods. +- Primitives must be as fast and lightweight as possible. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Yechim biroz noqulay ko'rinadi, ammo bu yerda: @@ -50,7 +55,11 @@ Yechim biroz noqulay ko'rinadi, ammo bu yerda: 2. Til matnlar, raqamlar, mantiqiy turdagi qiymatlar va belgilarning usullari va xususiyatlariga kirishga imkon beradi. 3. Bu sodir bo'lganda, qo'shimcha funktsiyalarni ta'minlaydigan maxsus "o'ralish-obyekti" yaratiladi va keyin yo'q qilinadi. +<<<<<<< HEAD "O'ralish-obyekti" har bir ibtidoiy tur uchun har xil va ular quyidagicha nomlanadi: `String`, `Number`, `Boolean` va `Symbol`. Shunday qilib, ular turli xil usullar to'plamini taqdim etadilar. +======= +The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. Thus, they provide different sets of methods. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) usuli mavjud , bu tepa registr matni qaytaradi. @@ -106,10 +115,17 @@ if (zero) { } ``` +<<<<<<< HEAD Boshqa tomondan, xuddi shu `String/Number/Boolean` funktsiyalaridan `new` dan foydalanish umuman foydali narsadir. Ular qiymatni tegishli turga o'zgartiradilar: matnga, raqamga yoki mantiqiy qiymatga(ibtidoiy). Misol uchun, quyidagi butunlay joizdir: +======= +On the other hand, using the same functions `String/Number/Boolean` without `new` is totally fine and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive). + +For example, this is entirely valid: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let num = Number("123"); // matni raqamga aylantirish ``` diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md index 919ac49f0..c8f6feacf 100644 --- a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md +++ b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md @@ -27,5 +27,9 @@ alert((6.35 * 10).toFixed(20)); // 63.50000000000000000000 E'tibor bering, `63.5` hech qanday aniq yo'qotishlarga ega emas. Buning sababi, `0,5` kasr qismi aslida `1/2` dir. `2` kuchlariga bo'linadigan qismlar ikkilik tizimda to'liq ifodalanadi, endi biz uni yaxlitlashimiz mumkin: ```js run +<<<<<<< HEAD alert(Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(yaxlitlangan) -> 6.4 +======= +alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(rounded) -> 6.4 +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md index 34f907329..43cb32a6c 100644 --- a/1-js/05-data-types/02-number/article.md +++ b/1-js/05-data-types/02-number/article.md @@ -2,9 +2,15 @@ Zamonaviy JavaScript-da ikki turdagi raqamlar mavjud: +<<<<<<< HEAD 1. JavaScript-da oddiy raqamlar 64-bitli [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) formatida saqlanadi, bu "ikki aniqlikdagi suzuvchi nuqta raqamlari" deb ham ataladi. Bular biz ko'pincha ishlatadigan raqamlar va bu bobda ular haqida gaplashamiz. 2. BigInt raqamlari ixtiyoriy uzunlikdagi butun sonlarni ifodalaydi. Ular ba'zan kerak bo'ladi, chunki oddiy butun son raqami xavfsiz ravishda (253-1) dan oshib ketishi yoki -(253-1) dan kichik bo'lishi mumkin emas, buni bobida eslatgan edik. Bigint'lar bir nechta maxsus sohalarda ishlatilganligi sababli, ularga maxsus bobini bag'ishlaymiz. +======= +1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter. + +2. BigInt numbers represent integers of arbitrary length. They are sometimes needed because a regular integer number can't safely exceed (253-1) or be less than -(253-1), as we mentioned earlier in the chapter . As bigints are used in a few special areas, we devote them to a special chapter . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Demak, bu yerda oddiy raqamlar haqida gaplashamiz. Ular haqidagi bilimlarimizni kengaytiraylik. @@ -22,7 +28,11 @@ Shuningdek, biz ajratuvchi sifatida pastki chiziq `_` dan foydalanishimiz mumkin let billion = 1_000_000_000; ``` +<<<<<<< HEAD Bu yerda pastki chiziq `_` "[sintaktik shakar](https://en.wikipedia.org/wiki/Syntactic_sugar)" rolini o'ynaydi, u raqamni o'qishga osonroq qiladi. JavaScript dvigateli raqamlar orasidagi `_` ni shunchaki e'tiborsiz qoldiradi, shuning uchun bu yuqoridagi bilan aynan bir xil bir milliarddir. +======= +Here the underscore `_` plays the role of the "[syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar)", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Haqiqiy hayotda biz nollarning uzun ketma-ketliklarini yozishdan qochamiz. Bunga dangasamiz. Bir milliard uchun `"1bn"` yoki 7 milliard 300 million uchun `"7.3bn"` kabi narsalar yozishga harakat qilamiz. Ko'pchilik katta raqamlar uchun ham xuddi shunday. @@ -37,16 +47,25 @@ alert(7.3e9); // 7.3 milliard (7300000000 yoki 7_300_000_000 bilan bir xil) Boshqacha qilib aytganda, `e` raqamni berilgan nollar soni bilan `1` ga ko'paytiradi. ```js +<<<<<<< HEAD 1e3 === 1 * 1000; // e3 *1000 ni anglatadi 1.23e6 === 1.23 * 1000000; // e6 *1000000 ni anglatadi ``` Endi juda kichik narsani yozaylik. Aytaylik, 1 mikrosekund (sekundning milliondan bir qismi): +======= +1e3 === 1 * 1000; // e3 means *1000 +1.23e6 === 1.23 * 1000000; // e6 means *1000000 +``` + +Now let's write something very small. Say, 1 microsecond (one-millionth of a second): +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let mсs = 0.000001; ``` +<<<<<<< HEAD Xuddi avvalgidek, `"e"` dan foydalanish yordam berishi mumkin. Nollarni aniq yozishdan qochish uchun xuddi shunday yoza olamiz: ```js @@ -54,10 +73,20 @@ let mcs = 1e-6; // 1 dan chapga beshta nol ``` Agar biz `0.000001` dagi nollarni sansak, ulardan 6 ta bor. Demak, tabiiy ravishda bu `1e-6`. +======= +Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could write the same as: + +```js +let mcs = 1e-6; // five zeroes to the left from 1 +``` + +If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Boshqacha qilib aytganda, `"e"` dan keyingi salbiy raqam berilgan nollar soni bilan 1 ga bo'lishni anglatadi: ```js +<<<<<<< HEAD // -3 berilgan 3 ta nol bilan 1 ga bo'ladi 1e-3 === 1 / 1000; // 0.001 @@ -66,6 +95,16 @@ Boshqacha qilib aytganda, `"e"` dan keyingi salbiy raqam berilgan nollar soni bi // kattaroq raqam bilan misol 1234e-2 === 1234 / 100; // 12.34, kasr nuqtasi 2 marta siljiydi +======= +// -3 divides by 1 with 3 zeroes +1e-3 === 1 / 1000; // 0.001 + +// -6 divides by 1 with 6 zeroes +1.23e-6 === 1.23 / 1000000; // 0.00000123 + +// an example with a bigger number +1234e-2 === 1234 / 100; // 12.34, decimal point moves 2 times +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ### Hex, binary va octal raqamlar @@ -103,13 +142,23 @@ alert(num.toString(16)); // ff alert(num.toString(2)); // 11111111 ``` +<<<<<<< HEAD `base` `2` dan `36` gacha o'zgarishi mumkin. Standart bo'yicha bu `10`. +======= +The `base` can vary from `2` to `36`. By default, it's `10`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Buning umumiy foydalanish holatlari: +<<<<<<< HEAD - **base=16** hex ranglar, belgi kodlashlari va hokazo uchun ishlatiladi, raqamlar `0..9` yoki `A..F` bo'lishi mumkin. - **base=2** asosan bitli operatsiyalarni disk raskadka qilish uchun, raqamlar `0` yoki `1` bo'lishi mumkin. - **base=36** maksimal, raqamlar `0..9` yoki `A..Z` bo'lishi mumkin. Butun Lotin alifbosi raqamni ifodalash uchun ishlatiladi. `36` uchun qiziqarli, lekin foydali holat - uzun raqamli identifikatorni qisqaroq narsaga aylantirish kerak bo'lganda, masalan, qisqa url yaratish uchun. Uni shunchaki `36` asosli raqam tizimida ifodalash mumkin: +======= +- **base=16** is used for hex colors, character encodings etc, digits can be `0..9` or `A..F`. +- **base=2** is mostly for debugging bitwise operations, digits can be `0` or `1`. +- **base=36** is the maximum, digits can be `0..9` or `A..Z`. The whole Latin alphabet is used to represent a number. A funny, but useful case for `36` is when we need to turn a long numeric identifier into something shorter, for example, to make a short url. Can simply represent it in the numeral system with base `36`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert((123456).toString(36)); // 2n9c @@ -118,9 +167,16 @@ Buning umumiy foydalanish holatlari: ```warn header="Usulni chaqirish uchun ikkita nuqta" E'tibor bering, `123456..toString(36)` dagi ikkita nuqta xato emas. Agar biz yuqoridagi misoldagi `toString` kabi raqamda to'g'ridan-to'g'ri usulni chaqirmoqchi bo'lsak, undan keyin ikkita nuqta `..` qo'yishimiz kerak. +<<<<<<< HEAD Agar bitta nuqta qo'ysak: `123456.toString(36)`, u holda xato bo'ladi, chunki JavaScript sintaksisi birinchi nuqtadan keyin kasr qismini nazarda tutadi. Va agar yana bir nuqta qo'ysak, JavaScript kasr qismi bo'sh ekanligini biladi va endi usulni ishlatadi. Shuningdek, `(123456).toString(36)` deb yoza olamiz. +======= +If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now uses the method. + +Also could write `(123456).toString(36)`. + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Yaxlitlash @@ -136,13 +192,18 @@ Yaxlitlash uchun bir nechta o'rnatilgan funksiyalar mavjud: : Yuqoriga yaxlitlaydi: `3.1` `4` ga aylanadi, `-1.1` `-1` ga aylanadi. `Math.round` +<<<<<<< HEAD : Eng yaqin butun songa yaxlitlaydi: `3.1` `3` ga aylanadi, `3.6` `4` ga aylanadi. O'rta holatlarda `3.5` `4` gacha yaxlitlanadi, `-3.5` `-3` gacha yaxlitlanadi. +======= +: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`. In the middle cases `3.5` rounds up to `4`, and `-3.5` rounds up to `-3`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `Math.trunc` (Internet Explorer tomonidan qo'llab-quvvatlanmaydi) : Yaxlitlashsiz kasr nuqtasidan keyin hamma narsani olib tashlaydi: `3.1` `3` ga aylanadi, `-1.1` `-1` ga aylanadi. Ular orasidagi farqlarni umumlashtiradigan jadval: +<<<<<<< HEAD | | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` | | ------ | ------------ | ----------- | ------------ | ------------ | | `3.1` | `3` | `4` | `3` | `3` | @@ -151,6 +212,16 @@ Ular orasidagi farqlarni umumlashtiradigan jadval: | `-1.1` | `-2` | `-1` | `-1` | `-1` | | `-1.5` | `-2` | `-1` | `-1` | `-1` | | `-1.6` | `-2` | `-1` | `-2` | `-1` | +======= +| | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` | +|---|---------|--------|---------|---------| +|`3.1`| `3` | `4` | `3` | `3` | +|`3.5`| `3` | `4` | `4` | `3` | +|`3.6`| `3` | `4` | `4` | `3` | +|`-1.1`| `-2` | `-1` | `-1` | `-1` | +|`-1.5`| `-2` | `-1` | `-1` | `-1` | +|`-1.6`| `-2` | `-1` | `-2` | `-1` | +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu funksiyalar raqamning kasr qismi bilan ishlashning barcha mumkin bo'lgan usullarini qamrab oladi. Lekin agar raqamni kasr nuqtasidan keyin `n-chi` raqamga yaxlitlashni istasak-chi? @@ -162,8 +233,14 @@ Buning ikki usuli bor: Masalan, raqamni kasr nuqtasidan keyin 2-raqamga yaxlitlash uchun biz raqamni `100` ga ko'paytirib, yaxlitlash funksiyasini chaqirib, keyin orqaga bo'lishimiz mumkin. +<<<<<<< HEAD ```js run let num = 1.23456; +======= + For example, to round the number to the 2nd digit after the decimal, we can multiply the number by `100`, call the rounding function and then divide it back. + ```js run + let num = 1.23456; +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 alert(Math.round(num * 100) / 100); // 1.23456 -> 123.456 -> 123 -> 1.23 ``` @@ -182,20 +259,34 @@ Buning ikki usuli bor: alert(num.toFixed(1)); // "12.4" ``` +<<<<<<< HEAD E'tibor bering, `toFixed` ning natijasi satrdir. Agar kasr qismi kerakligidan qisqaroq bo'lsa, oxiriga nollar qo'shiladi: +======= + Please note that the result of `toFixed` is a string. If the decimal part is shorter than required, zeroes are appended to the end: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let num = 12.34; alert(num.toFixed(5)); // "12.34000", aynan 5 ta raqam qilish uchun nollar qo'shildi ``` +<<<<<<< HEAD Biz uni unary plus yoki `Number()` chaqiruvi yordamida raqamga aylantira olamiz, masalan `+num.toFixed(5)` deb yoza olamiz. +======= + We can convert it to a number using the unary plus or a `Number()` call, e.g. write `+num.toFixed(5)`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Noaniq hisoblar +<<<<<<< HEAD Ichki jihatdan raqam 64-bitli [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) formatida ifodalanadi, shuning uchun raqamni saqlash uchun aniq 64 bit mavjud: ulardan 52 tasi raqamlarni saqlash uchun, 11 tasi kasr nuqtasining o'rnini saqlash uchun va 1 bit belgi uchun ishlatiladi. Agar raqam haqiqatan ham juda katta bo'lsa, u 64-bitli xotirani to'ldirib, maxsus raqamli qiymat `Infinity` ga aylanishi mumkin: +======= +Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point, and 1 bit is for the sign. + +If a number is really huge, it may overflow the 64-bit storage and become a special numeric value `Infinity`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert(1e500); // Infinity @@ -203,7 +294,11 @@ alert(1e500); // Infinity Kamroq aniq bo'lishi mumkin, lekin tez-tez sodir bo'ladigan narsa - aniqlik yo'qolishi. +<<<<<<< HEAD Ushbu (noto'g'ri!) tenglik testini ko'rib chiqing: +======= +Consider this (falsy!) equality test: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert(0.1 + 0.2 == 0.3); // *!*false*/!* @@ -217,12 +312,34 @@ G'alati! U holda `0.3` bo'lmasa nima? alert(0.1 + 0.2); // 0.30000000000000004 ``` +<<<<<<< HEAD Voy! Tasavvur qiling, siz elektron xarid saytini yaratyapsiz va tashrif buyuruvchi savatiga `$0.10` va `$0.20` tovarlarni qo'yadi. Buyurtma umumiy summasi `$0.30000000000000004` bo'ladi. Bu har kimni hayratga soladi. +======= +Ouch! Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Lekin nima uchun bunday bo'ladi? Raqam xotirada binary shaklda, bitlar ketma-ketligi - birlar va nollar sifatida saqlanadi. Lekin o'nli raqam tizimida oddiy ko'rinadigan `0.1`, `0.2` kabi kasrlar aslida binary shaklida cheksiz kasrlardir. +<<<<<<< HEAD +======= +```js run +alert(0.1.toString(2)); // 0.0001100110011001100110011001100110011001100110011001101 +alert(0.2.toString(2)); // 0.001100110011001100110011001100110011001100110011001101 +alert((0.1 + 0.2).toString(2)); // 0.0100110011001100110011001100110011001100110011001101 +``` + +What is `0.1`? It is one divided by ten `1/10`, one-tenth. In the decimal numeral system, such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`. + +So, division by powers `10` is guaranteed to work well in the decimal system, but division by `3` is not. For the same reason, in the binary numeral system, the division by powers of `2` is guaranteed to work, but `1/10` becomes an endless binary fraction. + +There's just no way to store *exactly 0.1* or *exactly 0.2* using the binary system, just like there is no way to store one-third as a decimal fraction. + +The numeric format IEEE-754 solves this by rounding to the nearest possible number. These rounding rules normally don't allow us to see that "tiny precision loss", but it exists. + +We can see this in action: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert((0.1).toString(2)); // 0.0001100110011001100110011001100110011001100110011001101 alert((0.2).toString(2)); // 0.001100110011001100110011001100110011001100110011001101 @@ -235,12 +352,16 @@ Demak, `10` ning darajalariga bo'lish o'nli tizimda yaxshi ishlashi kafolatlanga Binary tizim yordamida _aniq 0.1_ yoki _aniq 0.2_ ni saqlashning hech qanday usuli yo'q, xuddi o'nli kasr sifatida uchdan birini saqlashning imkoni yo'qligi kabi. +<<<<<<< HEAD IEEE-754 raqamli formati buni eng yaqin mumkin bo'lgan raqamga yaxlitlash orqali hal qiladi. Bu yaxlitlash qoidalari odatda bizga "kichik aniqlik yo'qolishi" ni ko'rishga imkon bermaydi, lekin u mavjud. Buni amalda ko'rishimiz mumkin: ```js run alert((0.1).toFixed(20)); // 0.10000000000000000555 +======= +PHP, Java, C, Perl, and Ruby give exactly the same result, because they are based on the same numeric format. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` Va ikkita raqamni qo'shganimizda, ularning "aniqlik yo'qolishlari" qo'shiladi. @@ -257,7 +378,11 @@ Muammoni hal qila olamizmi? Albatta, eng ishonchli usul - natijani [toFixed(n)]( ```js run let sum = 0.1 + 0.2; +<<<<<<< HEAD alert(sum.toFixed(2)); // "0.30" +======= +alert( sum.toFixed(2) ); // "0.30" +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` E'tibor bering, `toFixed` har doim satr qaytaradi. U kasr nuqtasidan keyin 2 ta raqam borligini ta'minlaydi. Bu elektron xarid qilish saytimiz bo'lsa va `$0.30` ko'rsatish kerak bo'lsa, aslida qulay. Boshqa holatlarda uni raqamga aylantirish uchun unary plus ishlatishimiz mumkin: @@ -274,7 +399,11 @@ alert((0.1 * 10 + 0.2 * 10) / 10); // 0.3 alert((0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001 ``` +<<<<<<< HEAD Demak, ko'paytirish/bo'lish yondashuvi xatoni kamaytiradi, lekin uni butunlay olib tashlamaydi. +======= +So, the multiply/divide approach reduces the error, but doesn't remove it totally. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ba'zan kasrlardan butunlay qochishga harakat qilishimiz mumkin. Masalan, agar do'kon bilan ish qilayotgan bo'lsak, narxlarni dollar o'rniga sentda saqlashimiz mumkin. Lekin agar 30% chegirma qo'llasak-chi? Amalda kasrlardan butunlay qochish kamdan-kam mumkin. Kerak bo'lganda "dumlarni" kesish uchun shunchaki yaxlitlang. @@ -296,7 +425,11 @@ Raqamlarning ichki ko'rinishining yana bir qiziq natijasi - ikkita nolning mavju Buning sababi shundaki, belgi bitta bit bilan ifodalanadi, shuning uchun nolni o'z ichiga olgan har qanday raqam uchun o'rnatilishi yoki o'rnatilmasligi mumkin. +<<<<<<< HEAD Ko'p hollarda bu farq sezilmaydi, chunki operatorlar ularni bir xil deb ko'rishga moslashtirilgan. +======= +In most cases, the distinction is unnoticeable, because operators are suited to treat them as the same. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Testlar: isFinite va isNaN @@ -317,9 +450,13 @@ Ular `number` tipiga tegishli, lekin "oddiy" raqamlar emas, shuning uchun ularni Lekin bizga bu funksiya kerakmi? `=== NaN` solishtiruvidan foydalana olmaymizmi? Afsuski yo'q. `NaN` qiymati o'ziga ham teng kelmasligida noyobdir: +<<<<<<< HEAD ```js run alert(NaN === NaN); // false ``` +======= + But do we need this function? Can't we just use the comparison `=== NaN`? Unfortunately not. The value `NaN` is unique in that it does not equal anything, including itself: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - `isFinite(value)` o'z argumentini raqamga aylantiradi va agar u oddiy raqam bo'lsa `true` qaytaradi, `NaN/Infinity/-Infinity` bo'lmasa: @@ -338,6 +475,7 @@ let num = +prompt("Raqam kiriting", ""); alert(isFinite(num)); ``` +<<<<<<< HEAD E'tibor bering, bo'sh yoki faqat bo'shliq bo'lgan satr `isFinite` ni o'z ichiga olgan barcha raqamli funksiyalarda `0` deb hisoblanadi. ````smart header="`Number.isNaN`va`Number.isFinite`" @@ -348,12 +486,51 @@ E'tibor bering, bo'sh yoki faqat bo'shliq bo'lgan satr `isFinite` ni o'z ichiga ```js run alert(Number.isNaN(NaN)); // true alert(Number.isNaN("str" / 2)); // true +======= +Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`. + +````smart header="`Number.isNaN` and `Number.isFinite`" +[Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) and [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) methods are the more "strict" versions of `isNaN` and `isFinite` functions. They do not autoconvert their argument into a number, but check if it belongs to the `number` type instead. + +- `Number.isNaN(value)` returns `true` if the argument belongs to the `number` type and it is `NaN`. In any other case, it returns `false`. + + ```js run + alert( Number.isNaN(NaN) ); // true + alert( Number.isNaN("str" / 2) ); // true + + // Note the difference: + alert( Number.isNaN("str") ); // false, because "str" belongs to the string type, not the number type + alert( isNaN("str") ); // true, because isNaN converts string "str" into a number and gets NaN as a result of this conversion + ``` + +- `Number.isFinite(value)` returns `true` if the argument belongs to the `number` type and it is not `NaN/Infinity/-Infinity`. In any other case, it returns `false`. + + ```js run + alert( Number.isFinite(123) ); // true + alert( Number.isFinite(Infinity) ); // false + alert( Number.isFinite(2 / 0) ); // false + + // Note the difference: + alert( Number.isFinite("123") ); // false, because "123" belongs to the string type, not the number type + alert( isFinite("123") ); // true, because isFinite converts string "123" into a number 123 + ``` + +In a way, `Number.isNaN` and `Number.isFinite` are simpler and more straightforward than `isNaN` and `isFinite` functions. In practice though, `isNaN` and `isFinite` are mostly used, as they're shorter to write. +```` + +```smart header="Comparison with `Object.is`" +There is a special built-in method `Object.is` that compares values like `===`, but is more reliable for two edge cases: + +1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing. +2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's correct because internally the number has a sign bit that may be different even if all other bits are zeroes. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 // Farqga e'tibor bering: alert(Number.isNaN("str")); // false, chunki "str" string tipiga tegishli, number tipiga emas alert(isNaN("str")); // true, chunki isNaN "str" satrini raqamga aylantiradi va bu aylantirishning natijasida NaN ni oladi ``` +<<<<<<< HEAD - `Number.isFinite(value)` agar argument `number` tipiga tegishli bo'lsa va u `NaN/Infinity/-Infinity` bo'lmasa `true` qaytaradi. Boshqa barcha hollarda `false` qaytaradi. ```js run @@ -379,6 +556,9 @@ Ma'lum ma'noda `Number.isNaN` va `Number.isFinite` `isNaN` va `isFinite` funksiy Boshqa barcha hollarda `Object.is(a, b)` `a === b` bilan bir xil. Biz bu yerda `Object.is` ni eslatamiz, chunki u JavaScript spetsifikatsiyasida tez-tez ishlatiladi. Ichki algoritm ikkita qiymatni aynan bir xil ekanligi uchun solishtirishga kerak bo'lganda, u `Object.is` dan foydalanadi (ichki jihatdan [SameValue](https://tc39.github.io/ecma262/#sec-samevalue) deb ataladi). +======= +We mention `Object.is` here, because it's often used in JavaScript specification. When an internal algorithm needs to compare two values for being exactly the same, it uses `Object.is` (internally called [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## parseInt va parseFloat @@ -391,7 +571,11 @@ alert( +"100px" ); // NaN Yagona istisno - satrning boshida yoki oxirida bo'shliqlar, ular e'tiborga olinmaydi. +<<<<<<< HEAD Lekin haqiqiy hayotda bizda ko'pincha CSS dagi `"100px"` yoki `"12pt"` kabi birliklardagi qiymatlar bor. Shuningdek, ko'plab mamlakatlarda valyuta belgisi miqdordan keyin keladi, shuning uchun bizda `"19€"` bor va undan raqamli qiymat chiqarishni istaydi. +======= +But in real life, we often have values in units, like `"100px"` or `"12pt"` in CSS. Also in many countries, the currency symbol goes after the amount, so we have `"19€"` and would like to extract a numeric value out of that. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `parseInt` va `parseFloat` buning uchun. @@ -437,8 +621,13 @@ Bir nechta misol: alert( Math.random() ); // ... (har qanday tasodifiy raqamlar) ``` +<<<<<<< HEAD `Math.max(a, b, c...)` va `Math.min(a, b, c...)` : Ixtiyoriy miqdordagi argumentlardan eng katta va eng kichigini qaytaradi. +======= +`Math.max(a, b, c...)` and `Math.min(a, b, c...)` +: Returns the greatest and smallest from the arbitrary number of arguments. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert( Math.max(3, 5, -10, 0, 1) ); // 5 @@ -467,7 +656,18 @@ Turli raqam tizimlari uchun: - `parseInt(str, base)` `str` satrini berilgan `base` asosli raqam tizimida butun songa tahlil qiladi, `2 ≤ base ≤ 36`. - `num.toString(base)` raqamni berilgan `base` asosli raqam tizimida satrga aylantiradi. +<<<<<<< HEAD Oddiy raqam testlari uchun: +======= +For regular number tests: + +- `isNaN(value)` converts its argument to a number and then tests it for being `NaN` +- `Number.isNaN(value)` checks whether its argument belongs to the `number` type, and if so, tests it for being `NaN` +- `isFinite(value)` converts its argument to a number and then tests it for not being `NaN/Infinity/-Infinity` +- `Number.isFinite(value)` checks whether its argument belongs to the `number` type, and if so, tests it for not being `NaN/Infinity/-Infinity` + +For converting values like `12pt` and `100px` to a number: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - `isNaN(value)` o'z argumentini raqamga aylantiradi va keyin uni `NaN` ekanligini tekshiradi - `Number.isNaN(value)` argumenti `number` tipiga tegishli ekanligini tekshiradi va agar shunday bo'lsa, uni `NaN` ekanligini tekshiradi @@ -480,9 +680,13 @@ Oddiy raqam testlari uchun: Kasrlar uchun: +<<<<<<< HEAD - `Math.floor`, `Math.ceil`, `Math.trunc`, `Math.round` yoki `num.toFixed(precision)` yordamida yaxlitlang. - Kasrlar bilan ishlashda aniqlik yo'qolishi borligini eslashni unutmang. Ko'proq matematik funksiyalar: - Kerak bo'lganda [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) obyektiga qarang. Kutubxona juda kichik, lekin asosiy ehtiyojlarni qoplashi mumkin. +======= +- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small but can cover basic needs. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/05-data-types/03-string/1-ucfirst/solution.md b/1-js/05-data-types/03-string/1-ucfirst/solution.md index d9cb5ab75..f57cf60ef 100644 --- a/1-js/05-data-types/03-string/1-ucfirst/solution.md +++ b/1-js/05-data-types/03-string/1-ucfirst/solution.md @@ -8,12 +8,16 @@ let newStr = str[0].toUpperCase() + str.slice(1); Ammo kichik bir muammo bor. Agar `str` bo'sh bo'lsa, unda `str[0]` aniqlanmagan(undefined), shuning uchun xato bo'ladi. +<<<<<<< HEAD Bu yerda ikkita variant mavjud: 1. `str.charAt(0)` dan foydalanish, chunki u har doim matni qaytaradi (ehtimol bo'sh). 2. Bo'sh satr uchun test qo'shish. Mana, ikkinchi variant: +======= +The easiest way out is to add a test for an empty string, like this: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run demo function ucFirst(str) { diff --git a/1-js/05-data-types/03-string/3-truncate/task.md b/1-js/05-data-types/03-string/3-truncate/task.md index 11dea5d1c..2f33654cf 100644 --- a/1-js/05-data-types/03-string/3-truncate/task.md +++ b/1-js/05-data-types/03-string/3-truncate/task.md @@ -11,7 +11,13 @@ Funktsiyaning natijasi kesilgan (kerak bo'lsa) matn bo'lishi kerak. Masalan: ```js +<<<<<<< HEAD truncate("Ushbu mavzu bo'yicha men aytmoqchi bo'lgan narsa:", 20) = "Ushbu mavzu bo'yicha..." truncate("Hammaga salom!", 20) = "Hammaga salom!" +======= +truncate("What I'd like to tell on this topic is:", 20) == "What I'd like to te…" + +truncate("Hi everyone!", 20) == "Hi everyone!" +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index 86b8abcd6..60a9e9ec3 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -48,9 +48,15 @@ let guestList = "Mehmonlar: // Xato: Unexpected token ILLEGAL * John"; ``` +<<<<<<< HEAD Bitta va qo'sh qo'shtirnoqlar tilning yaratilishi qadimgi davrlaridan keladi, o'sha paytda ko'p qatorli satrlar ehtiyoji hisobga olinmagan edi. Teskari qo'shtirnoqlar ancha keyinroq paydo bo'lgan va shuning uchun ko'proq imkoniyatlarga ega. Teskari qo'shtirnoqlar shuningdek birinchi teskari qo'shtirnoqdan oldin "shablon funksiyasini" belgilashga imkon beradi. Sintaksis: func`string`. `func` funksiyasi avtomatik ravishda chaqiriladi, satr va kiritilgan ifodalarni oladi va ularni qayta ishlashi mumkin. Bu xususiyat "teglangan shablonlar" deb ataladi, u kamdan-kam uchraydi, lekin bu haqda MDN da o'qishingiz mumkin: [Template literals](mdn:/JavaScript/Reference/Template_literals#Tagged_templates). +======= +Single and double quotes come from ancient times of language creation, when the need for multiline strings was not taken into account. Backticks appeared much later and thus are more versatile. + +Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`. The function `func` is called automatically, receives the string and embedded expressions and can process them. This feature is called "tagged templates", it's rarely seen, but you can read about it in the MDN: [Template literals](mdn:/JavaScript/Reference/Template_literals#Tagged_templates). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Maxsus belgilar @@ -59,10 +65,17 @@ Bitta va qo'sh qo'shtirnoqlar bilan ham ko'p qatorli satrlarni "yangi qator belg ```js run let guestList = "Mehmonlar:\n * John\n * Pete\n * Mary"; +<<<<<<< HEAD alert(guestList); // ko'p qatorli mehmonlar ro'yxati, yuqoridagi bilan bir xil ``` Oddiy misolda, bu ikki qator teng, shunchaki boshqacha yozilgan: +======= +alert(guestList); // a multiline list of guests, same as above +``` + +As a simpler example, these two lines are equal, just written differently: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let str1 = "Salom\nDunyo"; // "yangi qator belgisi" yordamida ikki qator @@ -74,6 +87,7 @@ Dunyo`; alert(str1 == str2); // true ``` +<<<<<<< HEAD Boshqa, kamroq uchraydigan maxsus belgilar ham bor: | Belgi | Tavsif | @@ -96,6 +110,30 @@ alert(`Teskari chiziq: \\`); // Teskari chiziq: \ "Qochgan" qo'shtirnoqlar `\'`, `\"`, \\` bir xil qo'shtirnoqli satrga qo'shtirnoq kiritish uchun ishlatiladi. Masalan: +======= +There are other, less common special characters: + +| Character | Description | +|-----------|-------------| +|`\n`|New line| +|`\r`|In Windows text files a combination of two characters `\r\n` represents a new break, while on non-Windows OS it's just `\n`. That's for historical reasons, most Windows software also understands `\n`. | +|`\'`, `\"`, \\`|Quotes| +|`\\`|Backslash| +|`\t`|Tab| +|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- mentioned for completeness, coming from old times, not used nowadays (you can forget them right now). | + +As you can see, all special characters start with a backslash character `\`. It is also called an "escape character". + +Because it's so special, if we need to show an actual backslash `\` within the string, we need to double it: + +```js run +alert( `The backslash: \\` ); // The backslash: \ +``` + +So-called "escaped" quotes `\'`, `\"`, \\` are used to insert a quote into the same-quoted string. + +For instance: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert("Men*!*'*/!*m Walrus!"); // *!*Men'm*/!* Walrus! @@ -106,6 +144,7 @@ Ko'rib turganingizdek, ichki qo'shtirnoqdan oldin teskari chiziq `\'` qo'yishimi Albatta, faqat o'rab turgan qo'shtirnoqlar bilan bir xil qo'shtirnoqlarni qochirish kerak. Shuning uchun yanada nafis yechim sifatida biz qo'sh qo'shtirnoq yoki teskari qo'shtirnoqga o'tishimiz mumkin: ```js run +<<<<<<< HEAD alert("Men'm Walrus!"); // Men'm Walrus! ``` @@ -118,6 +157,12 @@ Bu maxsus belgilardan tashqari, Unicode kodlari uchun maxsus notation `\u…` ha ```js run alert(`Men\n`.length); // 3 ``` +======= +alert( "I'm the Walrus!" ); // I'm the Walrus! +``` + +Besides these special characters, there's also a special notation for Unicode codes `\u…`, it's rarely used and is covered in the optional chapter about [Unicode](info:unicode). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 E'tibor bering, `\n` bitta "maxsus" belgi, shuning uchun uzunlik haqiqatan ham `3`. @@ -144,15 +189,25 @@ alert( str[str.length - 1] ); // m alert( str.at(-1) ); ```` +<<<<<<< HEAD Ko'rib turganingizdek, `.at(pos)` usuli salbiy pozitsiyaga imkon berishning afzalligiga ega. Agar `pos` salbiy bo'lsa, u satr oxiridan hisoblanadi. +======= +Please note that `str.length` is a numeric property, not a function. There is no need to add parenthesis after it. Not `.length()`, but `.length`. +``` +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Demak `.at(-1)` oxirgi belgini, `.at(-2)` undan oldingi belgini va hokazo anglatadi. +<<<<<<< HEAD Kvadrat qavslar salbiy indekslar uchun har doim `undefined` qaytaradi, masalan: +======= +To get a character at position `pos`, use square brackets `[pos]` or call the method [str.at(pos)](mdn:js/String/at). The first character starts from the zero position: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let str = `Salom`; +<<<<<<< HEAD alert(str[-2]); // undefined alert(str.at(-2)); // l ``` @@ -162,6 +217,35 @@ Shuningdek, `for..of` yordamida belgilar bo'ylab iteratsiya qilishimiz mumkin: ```js run for (let char of "Salom") { alert(char); // S,a,l,o,m (char "S" bo'ladi, keyin "a", keyin "l" va hokazo) +======= +// the first character +alert( str[0] ); // H +alert( str.at(0) ); // H + +// the last character +alert( str[str.length - 1] ); // o +alert( str.at(-1) ); +``` + +As you can see, the `.at(pos)` method has a benefit of allowing negative position. If `pos` is negative, then it's counted from the end of the string. + +So `.at(-1)` means the last character, and `.at(-2)` is the one before it, etc. + +The square brackets always return `undefined` for negative indexes, for instance: + +```js run +let str = `Hello`; + +alert( str[-2] ); // undefined +alert( str.at(-2) ); // l +``` + +We can also iterate over characters using `for..of`: + +```js run +for (let char of "Hello") { + alert(char); // H,e,l,l,o (char becomes "H", then "e", then "l" etc) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 } ``` @@ -204,7 +288,11 @@ alert("Interface".toLowerCase()); // interface Yoki agar bitta belgini kichik harfga o'tkazmoqchi bo'lsak: ```js run +<<<<<<< HEAD alert("Interface"[0].toLowerCase()); // 'i' +======= +alert( 'Interface'[0].toLowerCase() ); // 'i' +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Substring qidirish @@ -324,8 +412,13 @@ alert("Widget".includes("id", 3)); // false, 3-pozitsiyadan "id" yo'q [str.startsWith](mdn:js/String/startsWith) va [str.endsWith](mdn:js/String/endsWith) usullari aynan ular aytganini qiladi: ```js run +<<<<<<< HEAD alert("*!*Wid*/!*get".startsWith("Wid")); // true, "Widget" "Wid" bilan boshlanadi alert("Wid*!*get*/!*".endsWith("get")); // true, "Widget" "get" bilan tugaydi +======= +alert( "*!*Wid*/!*get".startsWith("Wid") ); // true, "Widget" starts with "Wid" +alert( "Wid*!*get*/!*".endsWith("get") ); // true, "Widget" ends with "get" +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Substring olish @@ -360,9 +453,15 @@ JavaScript-da substring olish uchun 3 ta usul mavjud: `substring`, `substr` va ` ``` `str.substring(start [, end])` +<<<<<<< HEAD : `start` va `end` _orasidagi_ satr qismini qaytaradi (`end` ni o'z ichiga olmaydi). Bu deyarli `slice` bilan bir xil, lekin `start` ning `end` dan katta bo'lishiga imkon beradi (bu holda u shunchaki `start` va `end` qiymatlarini almashtiradi). +======= +: Returns the part of the string *between* `start` and `end` (not including `end`). + + This is almost the same as `slice`, but it allows `start` to be greater than `end` (in this case it simply swaps `start` and `end` values). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan: @@ -398,9 +497,21 @@ JavaScript-da substring olish uchun 3 ta usul mavjud: `substring`, `substr` va ` alert( str.substr(-4, 2) ); // 'gi', 4-pozitsiyadan 2 ta belgi ol ``` +<<<<<<< HEAD Bu usul til spetsifikatsiyasining [Ilova B](https://tc39.es/ecma262/#sec-string.prototype.substr) da joylashgan. Bu faqat brauzer-joylashtirilgan JavaScript dvigatellari uni qo'llab-quvvatlashi kerakligini anglatadi va uni ishlatish tavsiya etilmaydi. Amalda u hamma joyda qo'llab-quvvatlanadi. Har qanday chalkashlikdan qochish uchun bu usullarni takrorlaylik: +======= + This method resides in the [Annex B](https://tc39.es/ecma262/#sec-string.prototype.substr) of the language specification. It means that only browser-hosted Javascript engines should support it, and it's not recommended to use it. In practice, it's supported everywhere. + +Let's recap these methods to avoid any confusion: + +| method | selects... | negatives | +|--------|-----------|-----------| +| `slice(start, end)` | from `start` to `end` (not including `end`) | allows negatives | +| `substring(start, end)` | between `start` and `end` (not including `end`)| negative values mean `0` | +| `substr(start, length)` | from `start` get `length` characters | allows negative `start` | +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 | usul | tanlaydi... | salbiylar | | ----------------------- | ------------------------------------------------------ | --------------------------------- | @@ -408,12 +519,18 @@ Har qanday chalkashlikdan qochish uchun bu usullarni takrorlaylik: | `substring(start, end)` | `start` va `end` orasida (`end` ni o'z ichiga olmaydi) | salbiy qiymatlar `0` ni anglatadi | | `substr(start, length)` | `start` dan `length` ta belgi ol | salbiy `start` ga ruxsat beradi | +<<<<<<< HEAD ```smart header="Qaysi birini tanlash kerak?" Ularning barchasi ishni bajara oladi. Rasmiy ravishda `substr` ning kichik kamchiligi bor: u JavaScript spetsifikatsiyasining asosiy qismida emas, balki brauzer-only xususiyatlarini qamrab oluvchi Ilova B da tasvirlangan va asosan tarixiy sabablarga ko'ra mavjud. Shuning uchun brauzer bo'lmagan muhitlar uni qo'llab-quvvatlamasligi mumkin. Lekin amalda u hamma joyda ishlaydi. Qolgan ikki variantdan `slice` biroz moslashuvchanroq, u salbiy argumentlarga imkon beradi va yozish qisqaroq. Shuning uchun amaliy foydalanish uchun faqat `slice` ni yodlab qolish kifoya. +======= +Of the other two variants, `slice` is a little bit more flexible, it allows negative arguments and shorter to write. + +So, for practical use it's enough to remember only `slice`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Satrlarni solishtirish @@ -436,6 +553,7 @@ Garchi, ba'zi g'alatiliklar bor. Bu mamlakat nomlarini saralasak g'alati natijalarga olib kelishi mumkin. Odatda odamlar `Zealand` ning ro'yxatda `Österreich` dan keyin kelishini kutadilar. +<<<<<<< HEAD Nima sodir bo'lishini tushunish uchun JavaScript-da satrlar [UTF-16](https://en.wikipedia.org/wiki/UTF-16) yordamida kodlanishini bilishimiz kerak. Ya'ni: har bir belgining mos raqamli kodi bor. Kod uchun belgini va teskarisini olish imkonini beradigan maxsus usullar mavjud: @@ -448,6 +566,20 @@ Kod uchun belgini va teskarisini olish imkonini beradigan maxsus usullar mavjud: alert( "Z".codePointAt(0) ); // 90 alert( "z".codePointAt(0) ); // 122 alert( "z".codePointAt(0).toString(16) ); // 7a (agar hex qiymat kerak bo'lsa) +======= +To understand what happens, we should be aware that strings in Javascript are encoded using [UTF-16](https://en.wikipedia.org/wiki/UTF-16). That is: each character has a corresponding numeric code. + +There are special methods that allow to get the character for the code and back: + +`str.codePointAt(pos)` +: Returns a decimal number representing the code for the character at position `pos`: + + ```js run + // different case letters have different codes + alert( "Z".codePointAt(0) ); // 90 + alert( "z".codePointAt(0) ); // 122 + alert( "z".codePointAt(0).toString(16) ); // 7a (if we need a hexadecimal value) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` `String.fromCodePoint(code)` @@ -455,10 +587,17 @@ Kod uchun belgini va teskarisini olish imkonini beradigan maxsus usullar mavjud: ```js run alert( String.fromCodePoint(90) ); // Z +<<<<<<< HEAD alert( String.fromCodePoint(0x5a) ); // Z (argument sifatida hex qiymatdan ham foydalanish mumkin) ``` Endi `65..220` kodli belgilarni (lotin alifbosi va biroz qo'shimcha) ko'rib, ulardan satr yasaylik: +======= + alert( String.fromCodePoint(0x5a) ); // Z (we can also use a hex value as an argument) + ``` + +Now let's see the characters with codes `65..220` (the latin alphabet and a little bit extra) by making a string of them: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let str = ""; @@ -466,9 +605,15 @@ let str = ""; for (let i = 65; i <= 220; i++) { str += String.fromCodePoint(i); } +<<<<<<< HEAD alert(str); // Chiqish: // ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ +======= +alert( str ); +// Output: +// ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„ +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 // ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜ ``` @@ -487,7 +632,11 @@ Satrlarni solishtirish uchun "to'g'ri" algoritm ko'ringanidan murakkabroq, chunk Shuning uchun brauzer qaysi tilda solishtirish kerakligini bilishi kerak. +<<<<<<< HEAD Yaxshiyamki, zamonaviy brauzerlar [ECMA-402](https://www.ecma-international.org/publications-and-standards/standards/ecma-402/) xalqarolashtirish standartini qo'llab-quvvatlaydi. +======= +Luckily, modern browsers support the internationalization standard [ECMA-402](https://www.ecma-international.org/publications-and-standards/standards/ecma-402/). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 U turli tillarda satrlarni ularning qoidalariga ko'ra solishtiradigan maxsus usulni taqdim etadi. @@ -505,6 +654,7 @@ alert("Österreich".localeCompare("Zealand")); // -1 Bu usul aslida [hujjatlarda](mdn:js/String/localeCompare) ko'rsatilgan ikkita qo'shimcha argumentga ega, bu tilni belgilash (sukut bo'yicha muhitdan olinadi, harflar tartibi tilga bog'liq) va registr sezgirlik yoki `"a"` va `"á"` bir xil deb qaralishi kerakmi kabi qo'shimcha qoidalarni o'rnatish imkonini beradi. +<<<<<<< HEAD ## Xulosa - 3 turdagi qo'shtirnoq bor. Teskari qo'shtirnoqlar satrning bir nechta qatorga cho'zilishi va ifodalarni `${…}` kiritish imkonini beradi. @@ -524,3 +674,24 @@ Satrlarda bir nechta boshqa foydali usullar ham bor: Satrlar muntazam ifodalar bilan qidirish/almashtirish uchun usullar ham bor. Lekin bu katta mavzu, shuning uchun u alohida o'quv qo'llanma bo'limida tushuntirilgan. Shuningdek, hozir satrlar Unicode kodlashiga asoslanganligini va shuning uchun solishtirishlar bilan muammolar borligini bilish muhim. Unicode haqida ko'proq ma'lumot bobida. +======= +## Summary + +- There are 3 types of quotes. Backticks allow a string to span multiple lines and embed expressions `${…}`. +- We can use special characters, such as a line break `\n`. +- To get a character, use: `[]` or `at` method. +- To get a substring, use: `slice` or `substring`. +- To lowercase/uppercase a string, use: `toLowerCase/toUpperCase`. +- To look for a substring, use: `indexOf`, or `includes/startsWith/endsWith` for simple checks. +- To compare strings according to the language, use: `localeCompare`, otherwise they are compared by character codes. + +There are several other helpful methods in strings: + +- `str.trim()` -- removes ("trims") spaces from the beginning and end of the string. +- `str.repeat(n)` -- repeats the string `n` times. +- ...and more to be found in the [manual](mdn:js/String). + +Strings also have methods for doing search/replace with regular expressions. But that's big topic, so it's explained in a separate tutorial section . + +Also, as of now it's important to know that strings are based on Unicode encoding, and hence there're issues with comparisons. There's more about Unicode in the chapter . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md index e76b5d199..3714beaa4 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md @@ -57,7 +57,11 @@ alert(getMaxSubSum([100, -9, 2, -3, 5])); // 100 Bu yechimning vaqt murakkabligi [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). Boshqacha qilib aytganda, agar array hajmini 2 marta oshirsak, algoritm 4 marta sekinroq ishlaydi. +<<<<<<< HEAD Katta array'lar (1000, 10000 yoki undan ko'p elementlar) uchun bunday algoritmlar jiddiy sekinlikka olib kelishi mumkin. +======= +For big arrays (1000, 10000 or more items) such algorithms can lead to serious sluggishness. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 # Tez yechim @@ -90,4 +94,8 @@ alert(getMaxSubSum([-1, -2, -3])); // 0 Algoritm aynan 1 marta array'ni o'tishni talab qiladi, shuning uchun vaqt murakkabligi O(n). +<<<<<<< HEAD Algoritm haqida batafsil ma'lumotni bu yerda topishingiz mumkin: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). Agar hali ham nima uchun ishlashi aniq bo'lmasa, yuqoridagi misollarda algoritmni kuzatib boring, qanday ishlashini ko'ring - bu har qanday so'zdan yaxshiroq. +======= +You can find more detailed information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md index d420dd4fb..7b2a809ca 100644 --- a/1-js/05-data-types/04-array/2-create-array/task.md +++ b/1-js/05-data-types/04-array/2-create-array/task.md @@ -6,11 +6,19 @@ muhimlik: 5 Keling, 5 ta massiv operatsiyasini sinab ko'raylik. +<<<<<<< HEAD 1. "Jazz" va "Blues" elementlari bilan massivni yarating. 2. "Rock-n-Roll" ni oxiriga qo'shing. 3. O'rtadagi qiymatni "Classics" bilan almashtiring. O'rtacha qiymatni topish uchun sizning kodingiz uzunlikdagi har qanday massivlar uchun ishlashi kerak. 4. Massivning birinchi qiymatini o'chirib tashang va uni ko'rsating. 5. Massivga `Rap` va `Reggae` ni oldinda qo'shing. +======= +1. Create an array `styles` with items "Jazz" and "Blues". +2. Append "Rock-n-Roll" to the end. +3. Replace the value in the middle with "Classics". Your code for finding the middle value should work for any arrays with odd length. +4. Strip off the first value of the array and show it. +5. Prepend `Rap` and `Reggae` to the array. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Jarayondagi massiv: diff --git a/1-js/05-data-types/04-array/3-call-array-this/task.md b/1-js/05-data-types/04-array/3-call-array-this/task.md index 4d3feb99f..4b4badc1c 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/task.md +++ b/1-js/05-data-types/04-array/3-call-array-this/task.md @@ -9,8 +9,13 @@ Natija qanday? Nima uchun? ```js let arr = ["a", "b"]; +<<<<<<< HEAD arr.push(function () { alert(this); +======= +arr.push(function() { + alert( this ); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 }); arr[2](); // ? diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index d65de650c..1a9af7ea4 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -92,6 +92,38 @@ let fruits = [ "Osilgan vergul" uslubi elementlarni kiritishni/olib tashlashni osonlashtiradi, chunki barcha satrlar bir xil bo'ladi. ```` +## Get last elements with "at" + +[recent browser="new"] + +Let's say we want the last element of the array. + +Some programming languages allow the use of negative indexes for the same purpose, like `fruits[-1]`. + +Although, in JavaScript it won't work. The result will be `undefined`, because the index in square brackets is treated literally. + +We can explicitly calculate the last element index and then access it: `fruits[fruits.length - 1]`. + +```js run +let fruits = ["Apple", "Orange", "Plum"]; + +alert( fruits[fruits.length-1] ); // Plum +``` + +A bit cumbersome, isn't it? We need to write the variable name twice. + +Luckily, there's a shorter syntax: `fruits.at(-1)`: + +```js run +let fruits = ["Apple", "Orange", "Plum"]; + +// same as fruits[fruits.length-1] +alert( fruits.at(-1) ); // Plum +``` + +In other words, `arr.at(i)`: +- is exactly the same as `arr[i]`, if `i >= 0`. +- for negative values of `i`, it steps back from the end of the array. ## Usullar pop/push, shift/unshift @@ -121,9 +153,17 @@ Stek odatda kartalar to'plami sifatida tasvirlanadi: yuqoriga yangi kartalar qo' JavaScript-dagi massivlar navbat sifatida ham, stek sifatida ham ishlashi mumkin. Ular sizga elementlarni boshiga yoki oxiriga qo'shish/olib tashlash imkonini beradi. +<<<<<<< HEAD Kompyuter fanida bunga imkon beradigan ma'lumotlar tuzilishi [deque](https://en.wikipedia.org/wiki/Double-ended_queue) deb nomlanadi. **Massiv oxiri bilan ishlaydigan usullar:** +======= +Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements, both to/from the beginning or the end. + +In computer science, the data structure that allows this, is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue). + +**Methods that work with the end of the array:** +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `pop` : Massivning oxirgi elementini ajratib oladi va qaytaradi: @@ -136,6 +176,8 @@ Kompyuter fanida bunga imkon beradigan ma'lumotlar tuzilishi [deque](https://en. alert( fruits ); // Olma, Apelsin ``` + Both `fruits.pop()` and `fruits.at(-1)` return the last element of the array, but `fruits.pop()` also modifies the array by removing it. + `push` : Elementni massivning oxiriga qo'shadi: @@ -245,7 +287,11 @@ Nega massivning boshidan ko'ra uning oxiri bilan ishlash tezroq? Keling, ijro pa fruits.shift(); // boshidan 1 ta elementni oling ``` +<<<<<<< HEAD Elementni `0` raqami bilan olib tashlash yetarli emas. Boshqa elementlarning ham raqamlarini o'zgartirish kerak. +======= +It's not enough to take and remove the element with the index `0`. Other elements need to be renumbered as well. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `shift` operatsiyasi uchta narsani bajarishi kerak: @@ -362,11 +408,19 @@ Massiv yaratish uchun yana bitta sintaksis mavjud: let arr = *!*new Array*/!*("Olma", "Nok", "va hokazo"); ``` +<<<<<<< HEAD U kamdan-kam qo'llaniladi, chunki to'rtburchaklar `[]` qisqaroq. Bundan tashqari, bu bilan juda ayyor xususiyati mavjud. +======= +It's rarely used, because square brackets `[]` are shorter. Also, there's a tricky feature with it. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Agar `new Array` raqamli bitta argument bilan chaqirilsa, u *elementlarsiz, lekin berilgan uzunlikdagi* massivni yaratadi. +<<<<<<< HEAD Keling, qanday qilib ayanchli xizmatni taqdim etishni ko'rib chiqaylik: +======= +Let's see how one can shoot themselves in the foot: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let arr = new Array(2); // u [2] massiv yaratadimi? @@ -391,7 +445,11 @@ let matrix = [ [7, 8, 9] ]; +<<<<<<< HEAD alert( matrix[1][1] ); // markaziy element +======= +alert( matrix[0][1] ); // 2, the second value of the first inner array +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## toString @@ -441,7 +499,7 @@ Let's recall the rules: - If one of the arguments of `==` is an object, and the other one is a primitive, then the object gets converted to primitive, as explained in the chapter . - ...With an exception of `null` and `undefined` that equal `==` each other and nothing else. -The strict comparison `===` is even simpler, as it doesn't convert types. +The strict comparison `===` is even simpler, as it doesn't convert types. So, if we compare arrays with `==`, they are never the same, unless we compare two variables that reference exactly the same array. @@ -461,7 +519,7 @@ alert( 0 == [] ); // true alert('0' == [] ); // false ``` -Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`. +Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`. Then the comparison process goes on with the primitives, as described in the chapter : @@ -481,6 +539,7 @@ That's simple: don't use the `==` operator. Instead, compare them item-by-item i Array - ro'yhatlangan ma'lumotlar elementlarini saqlash va boshqarish uchun mos bo'lgan maxsus ob'ekt turi. +<<<<<<< HEAD - Deklaratsiya: ```js @@ -492,6 +551,19 @@ Array - ro'yhatlangan ma'lumotlar elementlarini saqlash va boshqarish uchun mos ``` `new Arryay(raqam)` berilgan uzunlikdagi, ammo elementlarsiz massivni yaratadi. +======= +The declaration: + +```js +// square brackets (usual) +let arr = [item1, item2...]; + +// new Array (exceptionally rare) +let arr = new Array(item1, item2...); +``` + +The call to `new Array(number)` creates an array with the given length, but without elements. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 <<<<<<< HEAD - `length` xususiyati - bu massiv uzunligi yoki aniqrog'i, uning oxirgi son ko'rsatkichi plyus bir. U massiv usullari bilan avtomatik ravishda o'rnatiladi. @@ -501,7 +573,16 @@ Array - ro'yhatlangan ma'lumotlar elementlarini saqlash va boshqarish uchun mos - If we shorten `length` manually, the array is truncated. >>>>>>> fb4fc33a2234445808100ddc9f5e4dcec8b3d24c +<<<<<<< HEAD Biz quyidagi amallar bilan massivni ishlatishimiz mumkin: +======= +Getting the elements: + +- we can get element by its index, like `arr[0]` +- also we can use `at(i)` method that allows negative indexes. For negative values of `i`, it steps back from the end of the array. If `i >= 0`, it works same as `arr[i]`. + +We can use an array as a deque with the following operations: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 <<<<<<< HEAD - `push(...ma'lumot)` oxiriga `ma'lumot` qo'shiladi. diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md index 05683e011..29483a477 100644 --- a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md +++ b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md @@ -4,7 +4,11 @@ muhimlik: 4 # Massivdan kalitli obyekt yaratish +<<<<<<< HEAD Aytaylik, bizga `{id:..., name:..., age... }` shaklida foydalanuvchilar massivi keldi. +======= +Let's say we received an array of users in the form `{id:..., name:..., age:... }`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Undan obyekt yaratiladigan `groupById(arr)` funksiyasini yarating, bu yerda `id` kalit bo'lib, massiv elementlari qiymat bo'ladi. diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js index 110ce4fa3..52584156d 100644 --- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js +++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js @@ -2,12 +2,20 @@ describe("filterRangeInPlace", function () { it("filtrlangan qiymatlarni qaytaradi", function () { let arr = [5, 3, 8, 1]; +<<<<<<< HEAD filterRangeInPlace(arr, 1, 4); +======= + filterRangeInPlace(arr, 2, 5); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - assert.deepEqual(arr, [3, 1]); + assert.deepEqual(arr, [5, 3]); }); it("hech narsa qaytarmaydi", function () { assert.isUndefined(filterRangeInPlace([1, 2, 3], 1, 4)); }); +<<<<<<< HEAD +======= + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 }); diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md index 357a1f78f..32c55ca7e 100644 --- a/1-js/05-data-types/05-array-methods/article.md +++ b/1-js/05-data-types/05-array-methods/article.md @@ -1,6 +1,10 @@ # Massiv usullari +<<<<<<< HEAD Massivlar juda ko'p usullarni taqdim etadi. Ishlarni engillashtirish uchun ushbu bobda ular guruhlarga bo'lingan. +======= +Arrays provide a lot of methods. To make things easier, in this chapter, they are split into groups. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Elementlarni qo'shish/olib tashlash @@ -32,11 +36,19 @@ alert(arr.length); // 3 Element o'chirildi, ammo massivda hali ham 3 ta element mavjud, biz buni ko'rishimiz mumkin `arr.length == 3`. +<<<<<<< HEAD Bu tabiiy, chunki `obj.key` ni o'chirish `key` yordamida qiymatni olib tashlaydi. Hammasi shu. Obyektlar uchun yaxshi. Ammo massivlar uchun biz odatda qolgan elementlarning siljishini va bo'sh joyni egallashini istaymiz. Biz hozirda qisqaroq massivga ega bo'lishni kutmoqdamiz. +======= +That's natural, because `delete obj.key` removes a value by the `key`. It's all it does. Fine for objects. But for arrays we usually want the rest of the elements to shift and occupy the freed place. We expect to have a shorter array now. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shunday qilib, maxsus usullardan foydalanish kerak. +<<<<<<< HEAD [arr.splice(str)](mdn:js/Array/splice) usuli - bu massivlar uchun "Shveytsariya armiyasining pichog'i". U hamma narsani qilishi mumkin: elementlarni qo'shish, olib tashlash va kiritish. +======= +The [arr.splice](mdn:js/Array/splice) method is a Swiss army knife for arrays. It can do everything: insert, remove and replace elements. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Sintaksis: @@ -62,7 +74,11 @@ alert( arr ); // ["I", "JavaScript"] Oson, to‘g‘rimi? `1` indeksidan boshlab, u `1` elementni olib tashladi. +<<<<<<< HEAD Keyingi misolda biz uchta elementni olib tashlaymiz va ularni qolgan ikkitasi bilan almashtiramiz: +======= +In the next example, we remove 3 elements and replace them with the other two: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let arr = [*!*"I", "study", "JavaScript",*/!* "right", "now"]; @@ -84,7 +100,11 @@ let removed = arr.splice(0, 2); alert( removed ); // "I", "study" <-- o'chirilgan elementlarning massivi ``` +<<<<<<< HEAD `splice` usuli elementlarni hech qanday olib tashlamasdan kiritishga qodir. Buning uchun biz `deleteCount` ni `0` ga o'rnatishimiz kerak: +======= +The `splice` method is also able to insert the elements without any removals. For that, we need to set `deleteCount` to `0`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let arr = ["I", "study", "JavaScript"]; @@ -114,7 +134,11 @@ alert( arr ); // 1,2,3,4,5 ### slice +<<<<<<< HEAD [arr.slice](mdn:js/Array/slice) usuli o'xshash `arr.splice` ga qaraganda ancha sodda. +======= +The method [arr.slice](mdn:js/Array/slice) is much simpler than the similar-looking `arr.splice`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Sintaksis: @@ -124,7 +148,11 @@ arr.slice([start], [end]); U `"start"` dan `"end"` gacha (`"end"` hisobga olinmagan) barcha elementlarni o'z ichiga olgan yangi massivni qaytaradi. Har ikkala `start` va `end` ham salbiy bo'lishi mumkin, bu holda massiv oxiridan pozitsiya qabul qilinadi. +<<<<<<< HEAD U `str.slice` kabi ishlaydi, lekin submatnlar o'rniga submassivlar yaratadi. +======= +It's similar to a string method `str.slice`, but instead of substrings, it makes subarrays. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan: @@ -206,8 +234,13 @@ alert( arr.concat(arrayLike) ); // 1,2,something,else Sintaksis: ```js +<<<<<<< HEAD arr.forEach(function (item, index, array) { // ... item bilan biror narsa qilish +======= +arr.forEach(function(item, index, array) { + // ... do something with an item +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 }); ``` @@ -236,11 +269,22 @@ Bu massivda biror narsani qidirish usullari. [arr.indexOf](mdn:js/Array/indexOf), [arr.lastIndexOf](mdn:js/Array/lastIndexOf) va [arr.includes](mdn:js/Array/include) usullari bir xil sintaksisga ega. va aslida ularning matnga o'xshashadi, lekin belgilar o'rniga elementlarda ishlashadi: +<<<<<<< HEAD - `arr.indexOf(item, from)` `from` indeksdan boshlab `item` ni qidiradi va topilgan joyning indeksini qaytaradi, aks holda `-1`. - `arr.lastIndexOf(item, from)` -- xuddi shunday, lekin o'ngdan chapga qidiradi. - `arr.includes(item, from)` -- `from` indeksdan boshlab `item` ni izlaydi, agar topilsa `true` qiymatini beradi. Masalan: +======= +The methods [arr.indexOf](mdn:js/Array/indexOf) and [arr.includes](mdn:js/Array/includes) have the similar syntax and do essentially the same as their string counterparts, but operate on items instead of characters: + +- `arr.indexOf(item, from)` -- looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`. +- `arr.includes(item, from)` -- looks for `item` starting from index `from`, returns `true` if found. + +Usually, these methods are used with only one argument: the `item` to search. By default, the search is from the beginning. + +For instance: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let arr = [1, 0, false]; @@ -252,6 +296,7 @@ alert(arr.indexOf(null)); // -1 alert(arr.includes(1)); // true ``` +<<<<<<< HEAD E'tibor bering, usullarda `===` taqqoslash qo'llaniladi. Shunday qilib, agar biz `false` ni qidirsak, u nolni emas, balki `false` ni topadi. Agar biz inklyuziyani tekshirishni istasak va aniq indeksni bilmoqchi bo'lmasak, u holda `arr.includes` afzal. @@ -262,11 +307,41 @@ Bundan tashqari, `include` ning juda oz farqi shundaki, u `indexOf/lastIndexOf` const arr = [NaN]; alert(arr.indexOf(NaN)); // -1 (0 bo'lishi kerak, lekin === tenglik NaN uchun ishlamaydi) alert(arr.includes(NaN)); // true (to'g'ri) +======= +Please note that `indexOf` uses the strict equality `===` for comparison. So, if we look for `false`, it finds exactly `false` and not the zero. + +If we want to check if `item` exists in the array and don't need the index, then `arr.includes` is preferred. + +The method [arr.lastIndexOf](mdn:js/Array/lastIndexOf) is the same as `indexOf`, but looks for from right to left. + +```js run +let fruits = ['Apple', 'Orange', 'Apple'] + +alert( fruits.indexOf('Apple') ); // 0 (first Apple) +alert( fruits.lastIndexOf('Apple') ); // 2 (last Apple) ``` +````smart header="The `includes` method handles `NaN` correctly" +A minor, but noteworthy feature of `includes` is that it correctly handles `NaN`, unlike `indexOf`: + +```js run +const arr = [NaN]; +alert( arr.indexOf(NaN) ); // -1 (wrong, should be 0) +alert( arr.includes(NaN) );// true (correct) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 +``` +That's because `includes` was added to JavaScript much later and uses the more up-to-date comparison algorithm internally. +```` + +<<<<<<< HEAD ### find va findIndex Bizda bir obyektlar massivi mavjudligini tasavvur qiling. Muayyan shartli obyektni qanday topishimiz mumkin? +======= +### find and findIndex/findLastIndex + +Imagine we have an array of objects. How do we find an object with a specific condition? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu yerda [arr.find](mdn:js/Array/find) usuli foydalidir. @@ -285,7 +360,11 @@ Funktsiya massivning har bir elementi uchun takroriy ravishda chaqiriladi: - `index` bu uning indeksidir. - `array` massivning o'zi. +<<<<<<< HEAD Agar u `true` ni qaytarsa, qidiruv to'xtatiladi, `item` qaytariladi. Hech narsa topilmasa, `undefined` qaytariladi. +======= +If it returns `true`, the search is stopped, the `item` is returned. If nothing is found, `undefined` is returned. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, bizda foydalanuvchilar massivi bor, ularning har biri `id` va `name` argumentlariga ega. Keling, `id == 1` bilan topamiz: @@ -301,11 +380,38 @@ let user = users.find((item) => item.id == 1); alert(user.name); // John ``` +<<<<<<< HEAD Haqiqiy hayotda obyektlar massivi odatiy holdir, shuning uchun `find` usuli juda foydali. +======= +In real life, arrays of objects are a common thing, so the `find` method is very useful. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 E'tibor bering, biz misolda `item => item.id == 1` funktsiyasini bitta argument bilan `topish` ni ta'minlaymiz. Ushbu funktsiyaning boshqa argumentlari kamdan kam qo'llaniladi. +<<<<<<< HEAD [arr.findIndex](mdn:js/Array/findIndex) usuli asosan bir xil, ammo u elementning o'zi o'rniga element topilgan indeksni qaytaradi va hech narsa topilmaganda `-1` qaytariladi. +======= +The [arr.findIndex](mdn:js/Array/findIndex) method has the same syntax but returns the index where the element was found instead of the element itself. The value of `-1` is returned if nothing is found. + +The [arr.findLastIndex](mdn:js/Array/findLastIndex) method is like `findIndex`, but searches from right to left, similar to `lastIndexOf`. + +Here's an example: + +```js run +let users = [ + {id: 1, name: "John"}, + {id: 2, name: "Pete"}, + {id: 3, name: "Mary"}, + {id: 4, name: "John"} +]; + +// Find the index of the first John +alert(users.findIndex(user => user.name == 'John')); // 0 + +// Find the index of the last John +alert(users.findLastIndex(user => user.name == 'John')); // 3 +``` +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ### filter @@ -389,6 +495,11 @@ O'zimizning tartiblash usulimizdan foydalanish uchun biz ikkita argumentning fun Funktsiya shunday ishlashi kerak: +<<<<<<< HEAD +======= +The function should compare two arbitrary values and return: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js function compare(a, b) { if (a > b) return 1; // if the first value is greater than the second @@ -417,11 +528,19 @@ alert(arr); // *!*1, 2, 15*/!* Endi u maqsadga muvofiq ishlaydi. +<<<<<<< HEAD Keling, chetga chiqib, nima bo'layotganini o'ylab ko'raylik. `arr` har qanday narsaning massivi bo'lishi mumkin, shunday emasmi? Unda raqamlar yoki matnlar yoki HTML elementlari yoki boshqa narsalar bo'lishi mumkin. Bizda _bir narsa_ to'plami mavjud. Uni saralash uchun uning elementlarini taqqoslashni biladigan _tartiblash funktsiyasi_ kerak. Sukut bo'yicha matn tartibi. +======= +Let's step aside and think about what's happening. The `arr` can be an array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of *some items*. To sort it, we need an *ordering function* that knows how to compare its elements. The default is a string order. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `arr.sort(fn)` usuli tartiblash algoritmini o'rnatilgan dasturiga ega. Biz uning qanday ishlashiga ahamiyat berishimiz shart emas (ko'pincha optimallashtirilgan [quicksort](https://en.wikipedia.org/wiki/Quicksort)). U massivda yuradi, taqdim etilgan funktsiya yordamida elementlarini taqqoslaydi va ularni tartibini o'zgartiradi, bizga taqqoslashni amalga oshiradigan `fn` kerak bo'ladi. +<<<<<<< HEAD Aytgancha, qaysi elementlar taqqoslanganligini bilmoqchi bo'lsak -- ularni ogohlantirishga hech narsa to'sqinlik qilmaydi: +======= +By the way, if we ever want to know which elements are compared -- nothing prevents us from alerting them: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run [1, -2, 15, 2, 0, 8].sort(function (a, b) { @@ -477,7 +596,11 @@ Mana, hayotdagi holat. Biz xabar almashish dasturini yozmoqdamiz va odam qabul q [str.split(delim)](mdn:js/String/split) usuli aynan shu narsani qiladi. U matnni berilgan massivga ajratadi `delim`. +<<<<<<< HEAD Quyidagi misolda biz vergul bilan bo'sh joyni bo'ldik: +======= +In the example below, we split by a comma followed by a space: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let names = "Bilbo, Gandalf, Nazgul"; @@ -546,9 +669,15 @@ Funktsiya elementlarga qo'llaniladi. Siz 2-dan boshlab tanish bo'lgan argumentla Hozircha, `forEach/map` kabi. Ammo yana bir argument bor: +<<<<<<< HEAD - `previousValue` -- oldingi funktsiya chaqiruvining natijasidir, birinchi chaqiruv uchun `boshlang'ich`. Buni tushunishning eng oson usuli, bu misol. +======= +As the function is applied, the result of the previous function call is passed to the next one as the first argument. + +So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end, it becomes the result of `reduce`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu erda biz bitta satrda massiv yig'indisini olamiz: @@ -611,9 +740,15 @@ let arr = []; arr.reduce((sum, current) => sum + current); ``` +<<<<<<< HEAD Shuning uchun har doim boshlang'ich qiymatni ko'rsatish tavsiya etiladi. [arr.reduceRight](mdn:js/Array/reduceRight) usuli ham xuddi shunday qiladi, lekin o'ngdan chapga ishlaydi. +======= +So it's advised to always specify the initial value. + +The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same but goes from right to left. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Array.isArray @@ -622,8 +757,13 @@ Massivlar alohida til turini hosil qilmaydi. Ular obyektlarga asoslangan. Shunday qilib, `typeof` oddiy obyektni massivdan ajratishga yordam bermaydi: ```js run +<<<<<<< HEAD alert(typeof {}); // obyekt alert(typeof []); // bir xil +======= +alert(typeof {}); // object +alert(typeof []); // object (same) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ...Ammo massivlar shu qadar tez-tez ishlatiladiki, buning uchun maxsus usul mavjud: [Array.isArray(value)](mdn:js/Array/isArray). Agar `value` massiv bo'lsa, `true`, aks holda `false` ni qaytaradi. @@ -638,7 +778,11 @@ alert(Array.isArray([])); // true `find`, `filter`, `map` kabi funktsiyalarni chaqiradigan deyarli barcha massiv usullari, `sort` dan tashqari, `thisArg` qo'shimcha parametrlarini qabul qiladi. +<<<<<<< HEAD Ushbu parametr yuqoridagi bo'limlarda tushuntirilmagan, chunki u kamdan kam qo'llaniladi. Ammo to'liqlik uchun biz buni qoplashimiz kerak. +======= +That parameter is not explained in the sections above, because it's rarely used. But for completeness, we have to cover it. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Mana ushbu usullarning to'liq sintaksisi: @@ -696,22 +840,35 @@ Massiv usullaridan qo'llanma: - `slice(start, end)` -- yangi massiv yaratadi, elementlarni `start` dan `end` gacha (shu jumladan emas) massivga ko'chiradi. - `concat(...items)` -- yangi massivni qaytaradi: mavjud bo'lgan barcha a'zolarni nusxalaydi va unga `items` larni qo'shadi. Agar `items` ning birortasi massiv bo'lsa, unda uning elementlari olinadi. +<<<<<<< HEAD - Elementlar orasida qidirish uchun: - `indexOf/lastIndexOf(item, pos)` -- `pos` holatidan boshlab `item` ni qidiradi, va indeksni qaytaradi, topilmasa `-1` ni. - `includes(value)` -- agar massivda `value` bo'lsa `true`, aks holda `false` qaytariladi. - `find/filter(func)` -- funktsiya orqali elementlar filtrlaniladi, `true` qaytaradigan barcha qiymatlarni qaytaradi. - `findIndex` `find` ga o'xshaydi, lekin qiymat o'rniga indeksni qaytaradi. - Elementlar ustida takrorlash uchun: +======= +- To search among elements: + - `indexOf/lastIndexOf(item, pos)` -- look for `item` starting from position `pos`, and return the index or `-1` if not found. + - `includes(value)` -- returns `true` if the array has `value`, otherwise `false`. + - `find/filter(func)` -- filter elements through the function, return first/all values that make it return `true`. + - `findIndex` is like `find`, but returns the index instead of a value. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - `forEach(func)` -- har bir element uchun `func` ni chaqiradi, hech narsa qaytarmaydi. - Massivni o'zgartirish uchun: +<<<<<<< HEAD - `map(func)` -- har bir element uchun `func` ni chaqirish natijalaridan yangi massiv yaratadi. - `sort(func)` -- massivni joyida saralaydi, keyin qaytaradi. - `reverse()` -- massivni teskariga o'zgartiradi, keyin qaytaradi. - `split/join` -- matnni massivga va orqaga aylantiradi. - `reduce(func, initial)` -- har bir element uchun `func` chaqirib, chaqiruvlar orasidagi oraliq natijani berib, massiv ustida bitta qiymatni hisoblaydi. +======= +- Additionally: + - `Array.isArray(value)` checks `value` for being an array, if so returns `true`, otherwise `false`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - Qo'shimcha: - `Array.isArray(arr)` `arr` massiv ekanligini tekshiradi. @@ -724,7 +881,16 @@ Ushbu usullar eng ko'p ishlatiladigan usullar bo'lib, ular 99% holatlarni qamrab `fn` funktsiyasi massivning har bir elementida `map` ga o'xshash chaqiriladi. Agar natijala/natijalar `true` bo'lsa, `true`, aks holda `false` ni qaytaradi. +<<<<<<< HEAD - [arr.fill(value, start, end)](mdn:js/Array/fill) -- qatorni `start` dan `end` gacha takrorlanadigan `value` bilan to'ldiradi. +======= + We can use `every` to compare arrays: + + ```js run + function arraysEqual(arr1, arr2) { + return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]); + } +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - [arr.copyWithin(target, start, end)](mdn:js/Array/copyWithin) -- uning elementlarini `start` pozitsiyasidan `end` pozitsiyasiga _o'ziga_, `target` pozitsiyasida nusxalash (mavjudligini qayta yozish). @@ -734,4 +900,14 @@ Birinchi qarashdan juda ko'p usullar borligi esga olinishi qiyin tuyulishi mumki Ulardan xabardor bo'lish uchun qo'llanmani ko'rib chiqing. Keyin ushbu bobning vazifalarini amaliy ravishda hal qiling, shunda siz massiv usullari bilan tajribangizga ega bo'lasiz. +<<<<<<< HEAD Keyinchalik, qachondir siz massiv bilan biror narsa qilishingiz kerak bo'lsa va qanday qilishni bilmasangiz - bu yerga keling, qo'llanmaga qarang va to'g'ri usulni toping. Uni to'g'ri yozishga misollar yordam beradi. Yaqinda siz usullarni avtomatik ravishda eslab qolasiz. +======= +For the full list, see the [manual](mdn:js/Array). + +At first sight, it may seem that there are so many methods, quite difficult to remember. But actually, that's much easier. + +Look through the cheat sheet just to be aware of them. Then solve the tasks of this chapter to practice, so that you have experience with array methods. + +Afterwards whenever you need to do something with an array, and you don't know how -- come here, look at the cheat sheet and find the right method. Examples will help you to write it correctly. Soon you'll automatically remember the methods, without specific efforts from your side. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 0ec4a0c43..ab905c308 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -26,10 +26,17 @@ let range = { `range` ni ketma-ket sarraluvchan qilish uchun (va shunday qilib `for..of` ishlash uchun) biz obyektga `Symbol.iterator` nomli usulni qo'shishimiz kerak (buning uchun maxsus o'rnatilgan belgi). +<<<<<<< HEAD 1. `for..of` boshlanganda, u ushbu usulni bir marta chaqiradi (yoki topilmasa xatoni). Usul _ketma-ket sarraluvchan_ -- obyektni `next` usuli bilan qaytarishi kerak. 2. Aytgancha, `for..of` _faqat qaytib kelgan obyekt bilan ishlaydi_. 3. Agar `for..of` keyingi qiymatni xohlasa, u obyektda `next()` ni chaqiradi. 4. `next()` ning natijasi `{done: Boolean, value: any}` shaklida bo'lishi kerak, bu yerda `done = true` takrorlanish tugaganligini anglatadi, aks holda `value` yangi qiymat bo'lishi kerak. +======= +1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`. +2. Onward, `for..of` works *only with that returned object*. +3. When `for..of` wants the next value, it calls `next()` on that object. +4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the loop is finished, otherwise `value` is the next value. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `range` uchun to'liq dastur: @@ -39,10 +46,18 @@ let range = { to: 5, }; +<<<<<<< HEAD // 1. for..of chaqiruvi this ni chaqiradi range[Symbol.iterator] = function () { // ...ketma-ket sarraluvchan obyektini qaytaradi: // 2. for..of faqat ushbu ketma-ket sarraluvchan bilan ishlaydi, undan keyingi qiymatlarni so'raydi +======= +// 1. call to for..of initially calls this +range[Symbol.iterator] = function() { + + // ...it returns the iterator object: + // 2. Onward, for..of works only with the iterator object below, asking it for next values +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 return { current: this.from, last: this.to, @@ -172,7 +187,11 @@ Tabiiyki, bu xususiyatlar birlashtirilishi mumkin. Masalan, satrlar ketma-ket sa Ammo ketma-ket sarraluvchan massivga-o'xshash bo'lmasligi mumkin. Va aksincha, massivga-o'xshash ketma-ket sarraluvchan bo'lmasligi mumkin. +<<<<<<< HEAD Masalan, yuqoridagi misolda `range` ketma-ket sarraluvchan, lekin massivga-o'xshash emas, chunki u indekslangan xususiyatlarga va `uzunlikka` ega emas. +======= +But an iterable may not be array-like. And vice versa an array-like may not be iterable. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Va bu yerda obyekt massivga-o'xshash, ketma-ket sarraluvchan obyekt emas: @@ -214,8 +233,13 @@ alert(arr.pop()); // World (usul ishlaydi) Xuddi shu narsa ketma-ket sarraluvchan uchun sodir bo'ladi: +<<<<<<< HEAD ```js // ushbu range yuqoridagi misoldan olingan deb taxmin qilsak +======= +```js run +// assuming that range is taken from the example above +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 let arr = Array.from(range); alert(arr); // 1,2,3,4,5 (toString massivning konversiyasi ishlaydi) ``` @@ -230,8 +254,13 @@ Ikkinchi argument `mapFn` massivga qo'shilishdan oldin har bir elementga tatbiq Masalan: +<<<<<<< HEAD ```js // ushbu range yuqoridagi misoldan olingan deb taxmin qilsak +======= +```js run +// assuming that range is taken from the example above +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 // har bir sonning kvadrati let arr = Array.from(range, (num) => num * num); @@ -267,7 +296,11 @@ for (let char of str) { alert(chars); ``` +<<<<<<< HEAD ...Ammo qisqaroq. +======= +...But it is shorter. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Hatto surrogat juftlarini qo'llab-quvvatlaydigan `slice` yaratishimiz mumkin: diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index 809fe6707..7ff9c1994 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -9,10 +9,15 @@ Ammo bu real hayot uchun yetarli emas. Shuning uchun `Map` va `Set` ham mavjud. ## Map +<<<<<<< HEAD [Map](mdn:js/Map) - bu `Object` kabi kalitli ma'lumotlar to'plamidir. Lekin asosiy farq shundaki, `Map` har qanday turdagi kalitlarga ruxsat beradi. +======= +[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Metodlar va xususiyatlar: +<<<<<<< HEAD - `new Map()` -- xaritani yaratadi. - `map.set(key, value)` -- kalit bo'yicha qiymatni saqlaydi. - `map.get(key)` -- kalit bo'yicha qiymatni qaytaradi, agar `key` xaritada mavjud bo'lmasa `undefined` qaytaradi. @@ -20,6 +25,15 @@ Metodlar va xususiyatlar: - `map.delete(key)` -- kalit bo'yicha qiymatni o'chiradi. - `map.clear()` -- xaritadagi hamma narsani o'chiradi. - `map.size` -- hozirgi elementlar sonini qaytaradi. +======= +- [`new Map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map. +- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key. +- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map. +- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise. +- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element (the key/value pair) by the key. +- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map. +- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Misol uchun: @@ -99,15 +113,27 @@ map.set('1', 'str1') ``` ```` +<<<<<<< HEAD ## Map ustida iteratsiya `Map` ustida sikl uchun 3 ta metod mavjud: +======= +## Iteration over Map +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - `map.keys()` -- kalitlar uchun iterable qaytaradi, - `map.values()` -- qiymatlar uchun iterable qaytaradi, - `map.entries()` -- `[key, value]` yozuvlari uchun iterable qaytaradi, u `for..of` da standart bo'yicha ishlatiladi. +<<<<<<< HEAD Misol uchun: +======= +- [`map.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys) -- returns an iterable for keys, +- [`map.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values) -- returns an iterable for values, +- [`map.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries) -- returns an iterable for entries `[key, value]`, it's used by default in `for..of`. + +For instance: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let recipeMap = new Map([ @@ -160,7 +186,11 @@ let map = new Map([ alert( map.get('1') ); // str1 ``` +<<<<<<< HEAD Agar bizda oddiy objekt bor va undan `Map` yaratmoqchi bo'lsak, u holda [Object.entries(obj)](mdn:js/Object/entries) o'rnatilgan metodidan foydalanishimiz mumkin, u objekt uchun aynan shu formatdagi kalit/qiymat juftliklari massivini qaytaradi. +======= +If we have a plain object, and we'd like to create a `Map` from it, then we can use built-in method [Object.entries(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) that returns an array of key/value pairs for an object exactly in that format. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Shunday qilib objektdan xarita yaratishimiz mumkin: @@ -230,16 +260,29 @@ Bu bir xil, chunki `Object.fromEntries` argument sifatida iterable objektni kuta ## Set +<<<<<<< HEAD `Set` - bu maxsus turdagi to'plam - "qiymatlar to'plami" (kalitsiz), bu erda har bir qiymat faqat bir marta paydo bo'lishi mumkin. +======= +A [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) is a special type collection - "set of values" (without keys), where each value may occur only once. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Uning asosiy metodlari: +<<<<<<< HEAD - `new Set(iterable)` -- to'plamni yaratadi va agar `iterable` objekt berilgan bo'lsa (odatda massiv), undan qiymatlarni to'plamga nusxa ko'chiradi. - `set.add(value)` -- qiymat qo'shadi, to'plamning o'zini qaytaradi. - `set.delete(value)` -- qiymatni o'chiradi, chaqiruv momentida `value` mavjud bo'lsa `true`, aks holda `false` qaytaradi. - `set.has(value)` -- qiymat to'plamda mavjud bo'lsa `true`, aks holda `false` qaytaradi. - `set.clear()` -- to'plamdan hamma narsani o'chiradi. - `set.size` -- elementlar soni. +======= +- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, and if an `iterable` object is provided (usually an array), copies values from it into the set. +- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value, returns the set itself. +- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`. +- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`. +- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set. +- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Asosiy xususiyat shundaki, bir xil qiymat bilan `set.add(value)` ning takrorlangan chaqiruvlari hech narsa qilmaydi. Shuning uchun har bir qiymat `Set` da faqat bir marta paydo bo'ladi. @@ -269,7 +312,11 @@ for (let user of set) { } ``` +<<<<<<< HEAD `Set` ga alternativa foydalanuvchilar massivi bo'lishi mumkin va har bir kiritishda [arr.find](mdn:js/Array/find) dan foydalanib dublikatlarni tekshiradigan kod. Lekin ishlash ancha yomonroq bo'ladi, chunki bu metod har bir elementni tekshirib, butun massiv bo'ylab yuradi. `Set` noyoblikni tekshirish uchun ichki jihatdan ancha yaxshi optimallashtirilgan. +======= +The alternative to `Set` could be an array of users, and the code to check for duplicates on every insertion using [arr.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). But the performance would be much worse, because this method walks through the whole array checking every element. `Set` is much better optimized internally for uniqueness checks. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Set ustida iteratsiya @@ -288,20 +335,35 @@ set.forEach((value, valueAgain, set) => { Qiziq narsani qayd eting. `forEach` ga uzatilgan callback funktsiyasi 3 ta argumentga ega: `value`, keyin *bir xil qiymat* `valueAgain`, keyin maqsad objekt. Haqiqatan ham, bir xil qiymat argumentlarda ikki marta paydo bo'ladi. +<<<<<<< HEAD Bu `Map` bilan moslashish uchun, bu erda `forEach` ga uzatilgan callback uchta argumentga ega. Albatta, biroz g'alati ko'rinadi. Lekin `Map` ni `Set` bilan oson almashtirish va aksincha yordam berishi mumkin. +======= +That's for compatibility with `Map` where the callback passed `forEach` has three arguments. Looks a bit strange, for sure. But this may help to replace `Map` with `Set` in certain cases with ease, and vice versa. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `Map` da iteratorlar uchun bir xil metodlar `Set` da ham qo'llab-quvvatlanadi: +<<<<<<< HEAD - `set.keys()` -- qiymatlar uchun iterable objektni qaytaradi, - `set.values()` -- `set.keys()` bilan bir xil, `Map` bilan moslashish uchun, - `set.entries()` -- `[value, value]` yozuvlari uchun iterable objektni qaytaradi, `Map` bilan moslashish uchun mavjud. +======= +- [`set.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys) -- returns an iterable object for values, +- [`set.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values) -- same as `set.keys()`, for compatibility with `Map`, +- [`set.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries) -- returns an iterable object for entries `[value, value]`, exists for compatibility with `Map`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Xulosa +<<<<<<< HEAD `Map` -- kalitli qiymatlar to'plami. +======= +[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) -- is a collection of keyed values. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Metodlar va xususiyatlar: +<<<<<<< HEAD - `new Map([iterable])` -- xaritani yaratadi, boshlash uchun ixtiyoriy `iterable` (masalan, massiv) `[key,value]` juftliklari bilan. - `map.set(key, value)` -- kalit bo'yicha qiymatni saqlaydi, xaritaning o'zini qaytaradi. - `map.get(key)` -- kalit bo'yicha qiymatni qaytaradi, agar `key` xaritada mavjud bo'lmasa `undefined`. @@ -309,21 +371,43 @@ Metodlar va xususiyatlar: - `map.delete(key)` -- kalit bo'yicha qiymatni o'chiradi, chaqiruv momentida `key` mavjud bo'lsa `true`, aks holda `false` qaytaradi. - `map.clear()` -- xaritadagi hamma narsani o'chiradi. - `map.size` -- hozirgi elementlar sonini qaytaradi. +======= +- [`new Map([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization. +- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key, returns the map itself. +- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map. +- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise. +- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`. +- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map. +- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Oddiy `Object` dan farqlari: - Har qanday kalitlar, objektlar kalit bo'lishi mumkin. - Qo'shimcha qulay metodlar, `size` xususiyati. +<<<<<<< HEAD `Set` -- noyob qiymatlar to'plami. +======= +[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) -- is a collection of unique values. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Metodlar va xususiyatlar: +<<<<<<< HEAD - `new Set([iterable])` -- to'plamni yaratadi, boshlash uchun ixtiyoriy `iterable` (masalan, massiv) qiymatlar bilan. - `set.add(value)` -- qiymat qo'shadi (`value` mavjud bo'lsa hech narsa qilmaydi), to'plamning o'zini qaytaradi. - `set.delete(value)` -- qiymatni o'chiradi, chaqiruv momentida `value` mavjud bo'lsa `true`, aks holda `false` qaytaradi. - `set.has(value)` -- qiymat to'plamda mavjud bo'lsa `true`, aks holda `false` qaytaradi. - `set.clear()` -- to'plamdan hamma narsani o'chiradi. - `set.size` -- elementlar soni. +======= +- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, with optional `iterable` (e.g. array) of values for initialization. +- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value (does nothing if `value` exists), returns the set itself. +- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`. +- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`. +- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set. +- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `Map` va `Set` ustida iteratsiya har doim kiritish tartibida bo'ladi, shuning uchun biz bu to'plamlar tartibsiz deb ayta olmaymiz, lekin elementlarni qayta tartiblay olmaymiz yoki raqami bo'yicha to'g'ridan-to'g'ri element olishimiz mumkin emas. \ No newline at end of file diff --git a/1-js/05-data-types/08-weakmap-weakset/article.md b/1-js/05-data-types/08-weakmap-weakset/article.md index 3fdf4faaa..9e4c999a1 100644 --- a/1-js/05-data-types/08-weakmap-weakset/article.md +++ b/1-js/05-data-types/08-weakmap-weakset/article.md @@ -1,8 +1,18 @@ +<<<<<<< HEAD # WeakMap va WeakSet +======= + +# WeakMap and WeakSet +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 bo'limidan ma'lumki, JavaScript mexanizmi qiymatni xotirada "yetib boriladigan" bo'lib qolgan va potentsial ravishda ishlatilishi mumkin bo'lgan vaqt davomida saqlaydi. +<<<<<<< HEAD Misol uchun: +======= +For instance: + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js let john = { name: "John" }; @@ -54,13 +64,21 @@ john = null; // havolani qayta yozish */!* ``` +<<<<<<< HEAD `WeakMap` bu jihatdan tubdan farq qiladi. U kalit objektlarning garbage-collection qilinishiga to'sqinlik qilmaydi. +======= +[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is fundamentally different in this aspect. It doesn't prevent garbage-collection of key objects. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Misollar orqali bu nimani anglatishini ko'raylik. ## WeakMap +<<<<<<< HEAD `Map` va `WeakMap` o'rtasidagi birinchi farq shundaki, kalitlar objektlar bo'lishi kerak, primitiv qiymatlar emas: +======= +The first difference between [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is that keys must be objects, not primitive values: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let weakMap = new WeakMap(); @@ -94,10 +112,10 @@ Uni yuqoridagi oddiy `Map` misoli bilan solishtiring. Endi agar `john` faqat `We `WeakMap` faqat quyidagi metodlarga ega: -- `weakMap.get(key)` -- `weakMap.set(key, value)` -- `weakMap.delete(key)` -- `weakMap.has(key)` +- [`weakMap.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set) +- [`weakMap.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get) +- [`weakMap.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/delete) +- [`weakMap.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/has) Nega bunday cheklash? Bu texnik sabablarga ko'ra. Agar objekt boshqa barcha havolalarni yo'qotgan bo'lsa (yuqoridagi koddagi `john` kabi), u avtomatik ravishda garbage-collection qilinishi kerak. Lekin texnik jihatdan *tozalash qachon sodir bo'lishi* aniq belgilanmagan. @@ -182,6 +200,7 @@ function process(obj) { let result = /* obj uchun natijani hisoblash */; cache.set(obj, result); + return result; } return cache.get(obj); @@ -221,6 +240,7 @@ function process(obj) { let result = /* obj uchun natijani hisoblash */; cache.set(obj, result); + return result; } return cache.get(obj); @@ -242,11 +262,19 @@ obj = null; ## WeakSet +<<<<<<< HEAD `WeakSet` xuddi shunday harakat qiladi: - Bu `Set` ga o'xshash, lekin biz `WeakSet` ga faqat objektlar qo'shishimiz mumkin (primitivlar emas). - Objekt to'plamda boshqa joydan yetib boriladigan bo'lgancha mavjud. - `Set` kabi, u `add`, `has` va `delete` ni qo'llab-quvvatlaydi, lekin `size`, `keys()` va iteratsiyalar yo'q. +======= +[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) behaves similarly: + +- It is analogous to `Set`, but we may only add objects to `WeakSet` (not primitives). +- An object exists in the set while it is reachable from somewhere else. +- Like `Set`, it supports [`add`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/add), [`has`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/has) and [`delete`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/delete), but not `size`, `keys()` and no iterations. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 "Zaif" bo'lib, u ham qo'shimcha saqlash vazifasini bajaradi. Lekin ixtiyoriy ma'lumotlar uchun emas, balki "ha/yo'q" faktlari uchun. `WeakSet` dagi a'zolik objekt haqida biror narsani anglatishi mumkin. @@ -280,9 +308,15 @@ john = null; ## Xulosa +<<<<<<< HEAD `WeakMap` - bu `Map` ga o'xshash to'plam bo'lib, faqat objektlarga kalitlar sifatida ruxsat beradi va ular boshqa yo'llar bilan yetib borilmaydigan bo'lganda ular bilan bog'liq qiymat bilan birga olib tashlaydi. `WeakSet` - bu `Set` ga o'xshash to'plam bo'lib, faqat objektlarni saqlaydi va ular boshqa yo'llar bilan yetib borilmaydigan bo'lganda ularni olib tashlaydi. +======= +[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is `Map`-like collection that allows only objects as keys and removes them together with associated value once they become inaccessible by other means. + +[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) is `Set`-like collection that stores only objects and removes them once they become inaccessible by other means. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ularning asosiy afzalliklari shundaki, ular objektlarga zaif havola qiladi, shuning uchun ular garbage collector tomonidan osonlikcha olib tashlanishi mumkin. diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md index 575424922..d36eb661d 100644 --- a/1-js/05-data-types/09-keys-values-entries/article.md +++ b/1-js/05-data-types/09-keys-values-entries/article.md @@ -66,4 +66,39 @@ for (let value of Object.values(user)) { Xuddi `for..in` tsikl kabi, bu usullar ham `Symbol(...)` ni kalit sifatida ishlatadigan xususiyatlarga e'tibor bermaydi. +<<<<<<< HEAD Odatda bu qulay. Agar biz ham ramziy kalitlarni xohlasak, unda alohida usul mavjud [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols), bu faqat ramziy kalitlar massivini qaytaradi. Shuningdek, [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) usuli _hamma_ kalitlarni qaytaradi. +======= + +## Transforming objects + +Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others. + +If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`: + +1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`. +2. Use array methods on that array, e.g. `map`, to transform these key/value pairs. +3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object. + +For example, we have an object with prices, and would like to double them: + +```js run +let prices = { + banana: 1, + orange: 2, + meat: 4, +}; + +*!* +let doublePrices = Object.fromEntries( + // convert prices to array, map each key/value pair into another pair + // and then fromEntries gives back the object + Object.entries(prices).map(entry => [entry[0], entry[1] * 2]) +); +*/!* + +alert(doublePrices.meat); // 8 +``` + +It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/05-data-types/10-destructuring-assignment/article.md b/1-js/05-data-types/10-destructuring-assignment/article.md index 70c93ee21..6a2d31df5 100644 --- a/1-js/05-data-types/10-destructuring-assignment/article.md +++ b/1-js/05-data-types/10-destructuring-assignment/article.md @@ -2,6 +2,7 @@ JavaScript-dagi ikkita eng ko'p ishlatiladigan ma'lumotlar tuzilmasi `Object` va `Array`. +<<<<<<< HEAD Obyektlar ko'plab ma'lumotlarni bitta obyektga to'plashimizga imkon beradi va massivlar ro'yxatlangan to'plamlarni saqlashga imkon beradi. Shunday qilib, biz obyekt yoki massiv yaratib, uni bitta shaxs sifatida boshqarishimiz yoki uni funktsiya chaqiruviga o'tkazishimiz mumkin. *Destrukturalashtirish* - bu maxsus sintaksis, bu massivlarni yoki moslamalarni bir dasta o'zgaruvchanga "ochish" imkonini beradi, chunki ba'zida ular qulayroq bo'ladi. Destruktirizatsiya, shuningdek, juda ko'p parametrlarga, standart qiymatlarga ega bo'lgan murakkab funktsiyalar bilan juda yaxshi ishlaydi va tez orada biz ularni qanday ishlashini ko'rib chiqamiz. @@ -13,6 +14,24 @@ Qanday qilib massivning o'zgaruvchanga destrukturalashtirishga misol: ```js // bizda ism va familiya ko'rsatilgan massiv mavjud let arr = ["Ilya", "Kantor"] +======= +- Objects allow us to create a single entity that stores data items by key. +- Arrays allow us to gather data items into an ordered list. + +However, when we pass these to a function, we may not need all of it. The function might only require certain elements or properties. + +*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient. + +Destructuring also works well with complex functions that have a lot of parameters, default values, and so on. Soon we'll see that. + +## Array destructuring + +Here's an example of how an array is destructured into variables: + +```js +// we have an array with a name and surname +let arr = ["John", "Smith"] +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 *!* // destrukturalashtirish @@ -33,10 +52,19 @@ alert(firstName); // John alert(surname); // Smith ``` +<<<<<<< HEAD ````smart header="\"destrukturalashtirish\" degani \ "halokat \" degani emas." U "destrukturalashtirish" deb nomlanadi, chunki u elementlarni o'zgaruvchanga nusxalash orqali "buzadi". Ammo massivning o'zi o'zgartirilmaydi. Bu shunchaki yozishning qisqa usuli: +======= +As you can see, the syntax is simple. There are several peculiar details though. Let's see more examples to understand it better. + +````smart header="\"Destructuring\" does not mean \"destructive\"." +It's called "destructuring assignment," because it "destructurizes" by copying items into variables. However, the array itself is not modified. + +It's just a shorter way to write: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js // let [firstName, surname] = arr; let firstName = arr[0]; @@ -56,7 +84,11 @@ let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic alert( title ); // Consul ``` +<<<<<<< HEAD Yuqoridagi kodda massivning ikkinchi elementi o'tkazib yuboriladi, uchinchisiga `title` beriladi va massivning qolgan qismi ham o'tkazib yuboriladi. +======= +In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array items are also skipped (as there are no variables for them). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```` ````smart header="O'ng tomondagi har qanday ketma-ket saraluvchanlar bilan ishlaydi" @@ -67,11 +99,16 @@ Yuqoridagi kodda massivning ikkinchi elementi o'tkazib yuboriladi, uchinchisiga let [a, b, c] = "abc"; // ["a", "b", "c"] let [one, two, three] = new Set([1, 2, 3]); ``` -That works, because internally a destructuring assignment works by iterating over the right value. It's kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values. +That works, because internally a destructuring assignment works by iterating over the right value. It's a kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values. ```` +<<<<<<< HEAD ````smart header="Chap tarafdagi har qanday narsaga tayinlang" +======= +````smart header="Assign to anything at the left-side" +We can use any "assignables" on the left side. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biz chap tomonda har qanday "tayinlanadigan" narsalardan foydalanishimiz mumkin. @@ -86,11 +123,18 @@ alert(user.surname); // Smith ```` +<<<<<<< HEAD ````smart header=".entries() bilan tsiklash" Oldingi bobda biz [Object.entries(obj)](mdn:js/Object/entries) usulini ko'rdik. Obyektning kalitlari va qiymatlari ustida tsiklash uchun biz uni destrukturalashtiramiz: +======= +````smart header="Looping with .entries()" +In the previous chapter, we saw the [Object.entries(obj)](mdn:js/Object/entries) method. + +We can use it with destructuring to loop over the keys-and-values of an object: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let user = { @@ -98,7 +142,11 @@ let user = { age: 30 }; +<<<<<<< HEAD // kalitlari va qiymatlari ustida tsiklash +======= +// loop over the keys-and-values +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 *!* for (let [key, value] of Object.entries(user)) { */!* @@ -139,18 +187,37 @@ If we'd like also to gather all that follows -- we can add one more parameter th let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*]; *!* +<<<<<<< HEAD // "qolganlar" turi massiv ekanligini unutmang. +======= +// rest is an array of items, starting from the 3rd one +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 alert(rest[0]); // Consul alert(rest[1]); // of the Roman Republic alert(rest.length); // 2 */!* ``` +<<<<<<< HEAD `Rest` qiymati - bu qolgan qator elementlari massivi. Biz "rest" o'rniga boshqa har qanday o'zgaruvchan nomdan foydalanishimiz mumkin, shunchaki uning oldida uchta nuqta borligiga va destrukturalashtirishning oxirgi o'rinda turganiga ishonch hosil qiling. +======= +The value of `rest` is the array of the remaining array elements. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ### Sukut bo'yicha tayinlangan qiymatlar +<<<<<<< HEAD Agar massiv qiymatlar kamroq bo'lsa, tayinlashga nisbatan, xato bo'lmaydi. Yo'q qiymatlar `undefined` hisoblanadi: +======= +```js run +let [name1, name2, *!*...titles*/!*] = ["Julius", "Caesar", "Consul", "of the Roman Republic"]; +// now titles = ["Consul", "of the Roman Republic"] +``` + +### Default values + +If the array is shorter than the list of variables on the left, there will be no errors. Absent values are considered undefined: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run *!* @@ -197,7 +264,11 @@ Asosiy sintaksis: let {var1, var2} = {var1:…, var2:…} ``` +<<<<<<< HEAD O'ng tomonda mavjud bo'lgan obyektimiz bor, biz uni o'zgaruvchanlarga bo'lishni xohlaymiz. Chap tomonda tegishli xususiyatlar uchun "shablon" mavjud. Oddiy holatda, bu o'zgaruvchanlar nomlari ro'yxati `{...}`. +======= +We should have an existing object on the right side, that we want to split into variables. The left side contains an object-like "pattern" for corresponding properties. In the simplest case, that's a list of variable names in `{...}`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan: @@ -217,7 +288,13 @@ alert(width); // 100 alert(height); // 200 ``` +<<<<<<< HEAD Tegishli o'zgaruvchilarga `options.title`,` options.width` va `options.height` xususiyatlari tayinlaniladi. Tartib muhim emas. Bu ham ishlaydi: +======= +Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables. + +The order does not matter. This works too: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js // let{...} da xususiyatlar tartibini o'zgartirdi @@ -364,9 +441,15 @@ alert( title ); // Menu ## Ichki destrukturalashtirish +<<<<<<< HEAD Agar obyektda yoki massivda boshqa obyektlar va massivlar bo'lsa, biz chuqurroq qismlarni ajratib olish uchun murakkabroq chap tomon shablonlardan foydalanishimiz mumkin. Quyidagi kodda `options` `size` xususiyatida yana bir obyekt va `items` xususiyatidagi massiv mavjud. Biriktirishning chap tomonidagi shablon bir xil tuzilishga ega: +======= +If an object or an array contains other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions. + +In the code below `options` has another object in the property `size` and an array in the property `items`. The pattern on the left side of the assignment has the same structure to extract values from them: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let options = { @@ -375,7 +458,11 @@ let options = { height: 200 }, items: ["Cake", "Donut"], +<<<<<<< HEAD extra: true // biz yo'q qilmaydigan qo'shimcha narsa +======= + extra: true +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 }; // aniqlik uchun bir nechta chiziqlar bo'yicha destrukturalashtirish @@ -395,9 +482,13 @@ alert(item1); // Cake alert(item2); // Donut ``` +<<<<<<< HEAD `extra` dan tashqari barcha `options` obyekti tegishli o'zgaruvchanlarga tayinlangan. `size` va `items` ning o'zi buzilmaganligini unutmang. +======= +All properties of `options` object except `extra` which is absent in the left part, are assigned to corresponding variables: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ![](destructuring-complex.svg) @@ -411,11 +502,17 @@ Hatto bu erda ham shunday bo'ladi: let { size } = options; ``` +<<<<<<< HEAD ## Smart funktsiya parametrlari Funktsiya ko'p parametrlarga ega bo'lishi mumkin bo'lgan vaqtlar mavjud, ularning aksariyati ixtiyoriydir. Bu, ayniqsa, foydalanuvchi interfeyslariga taalluqlidir. Menyu yaratadigan funktsiyani tasavvur qiling. Uning kengligi, balandligi, sarlavhasi, buyumlar ro'yxati va boshqalar bo'lishi mumkin. Bunday funktsiyani yozishning yomon usuli: +======= +There are times when a function has many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, an item list and so on. + +Here's a bad way to write such a function: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js function showMenu(title = "Untitled", width = 200, height = 100, items = []) { @@ -423,7 +520,7 @@ function showMenu(title = "Untitled", width = 200, height = 100, items = []) { } ``` -In real-life, the problem is how to remember the order of arguments. Usually IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default. +In real-life, the problem is how to remember the order of arguments. Usually, IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default. Like this? @@ -488,7 +585,13 @@ function({ }) ``` +<<<<<<< HEAD Iltimos, shuni unutmangki, bunday destrukturalashtirish `showMenu()` ning argumentiga ega. Agar biz barcha qiymatlarni sukut bo'yicha tayinlangan bo'lishini xohlasak, unda bo'sh obyektni ko'rsatishimiz kerak: +======= +Then, for an object of parameters, there will be a variable `varName` for the property `incomingProperty`, with `defaultValue` by default. + +Please note that such destructuring assumes that `showMenu()` does have an argument. If we want all values by default, then we should specify an empty object: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js showMenu({}); // ok, all values are default @@ -515,7 +618,7 @@ Yuqoridagi kodda barcha argumentlar obyekti sukut bo'yicha `{}` dir, shuning uch - Destrukturalashtirish obyektni yoki massivni ko'plab o'zgaruvchanlarga zudlik bilan xaritalashga imkon beradi. - Obyekt sintaksis: ```js - let {prop : varName = default, ...rest} = object + let {prop : varName = defaultValue, ...rest} = object ``` Bu shuni anglatadiki, `prop` xususiyati `varName` o'zgaruvchaniga o'tishi kerak va agar bunday xususiyat bo'lmasa, u holda `default` qiymati ishlatilishi kerak. @@ -523,9 +626,13 @@ Yuqoridagi kodda barcha argumentlar obyekti sukut bo'yicha `{}` dir, shuning uch - Massiv sintaksis: ```js - let [item1 = default, item2, ...rest] = array + let [item1 = defaultValue, item2, ...rest] = array ``` +<<<<<<< HEAD Birinchi element `item1` ga o'tadi; ikkinchisi `item2` ga o'tadi, qolganlari esa `rest` massivini yaratadi. +======= + The first item goes to `item1`; the second goes into `item2`, and all the rest makes the array `rest`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - Keyinchalik murakkab holatlar uchun chap tomon o'ng tomoni bilan bir xil tuzilishga ega bo'lishi kerak. diff --git a/1-js/05-data-types/11-date/1-new-date/solution.md b/1-js/05-data-types/11-date/1-new-date/solution.md index 9c6195085..87fd9ac2c 100644 --- a/1-js/05-data-types/11-date/1-new-date/solution.md +++ b/1-js/05-data-types/11-date/1-new-date/solution.md @@ -13,7 +13,13 @@ alert(d1); Shuningdek, biz satrdan sana yaratishimiz mumkin, masalan: ```js run +<<<<<<< HEAD //new Date(sana_satri) let d2 = new Date("February 20, 2012 03:12:00"); alert(d2); +======= +//new Date(datastring) +let d2 = new Date("2012-02-20T03:12"); +alert( d2 ); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` diff --git a/1-js/05-data-types/11-date/article.md b/1-js/05-data-types/11-date/article.md index 3bd3c3950..309a879dc 100644 --- a/1-js/05-data-types/11-date/article.md +++ b/1-js/05-data-types/11-date/article.md @@ -53,7 +53,14 @@ Yangi `Sana` obyektini yaratish uchun quyidagi argumentlardan biri bilan `new Da `new Date(yil, oy, sana, saot, daqiqa, soniya, millisoniya)` : Belgilangan komponentlar bilan sanani mahalliy vaqt zonasida yarating. Faqat ikkita birinchi argument majburiydir. +<<<<<<< HEAD Eslatma: +======= + - The `year` should have 4 digits. For compatibility, 2 digits are also accepted and considered `19xx`, e.g. `98` is the same as `1998` here, but always using 4 digits is strongly encouraged. + - The `month` count starts with `0` (Jan), up to `11` (Dec). + - The `date` parameter is actually the day of month, if absent then `1` is assumed. + - If `hours/minutes/seconds/ms` is absent, they are assumed to be equal `0`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - `yil` 4 ta raqamdan iborat bo'lishi kerak: `2013` yaxshi, `98` yo'q. - Oylarni hisoblash `0` (yanvar) bilan boshlanadi, `11` gacha (dekabr). @@ -374,7 +381,11 @@ for (let i = 0; i < 10; i++) { ```warn header="Mikrobenchmarking qilishda ehtiyot bo'ling" Zamonaviy JavaScript interpretatorlari ko'plab optimallashtirishlarni amalga oshiradi. Ular "sun'iy sinovlar" natijalarini "odatdagi foydalanish" bilan taqqoslashlari mumkin, ayniqsa, biz juda kichik bir narsaga e'tibor qaratsak. Shunday qilib, agar siz ishlashni jiddiy tushunishni istasangiz, unda JavaScript-ni qanday ishlashini o'rganing. Va keyin sizga mikrobenchmarklar umuman kerak bo'lmaydi. +<<<<<<< HEAD V8 haqidagi maqolalar to'plamini sahifasida topishingiz mumkin. +======= +The great pack of articles about V8 can be found at . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Date.parse matndan @@ -405,7 +416,7 @@ Vaqt belgisidan darhol yangi `Date` obyektini yaratishimiz mumkin: ```js run let date = new Date( Date.parse('2012-01-26T13:51:50.417-07:00') ); -alert(date); +alert(date); ``` ## Xulosa diff --git a/1-js/05-data-types/12-json/article.md b/1-js/05-data-types/12-json/article.md index fabf0a144..d06a27994 100644 --- a/1-js/05-data-types/12-json/article.md +++ b/1-js/05-data-types/12-json/article.md @@ -27,7 +27,11 @@ Yaxshiyamki, bularning barchasini hal qilish uchun kod yozishning hojati yo'q. V ## JSON.stringify +<<<<<<< HEAD [JSON](http://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation) qiymatlar va moslamalarni aks ettirish uchun umumiy formatdir. U [RFC 4627](http://tools.ietf.org/html/rfc4627) standartidagi kabi tavsiflanadi. Dastlab u JavaScript uchun yaratilgan, ammo boshqa ko'plab tillarda ham uni boshqarish uchun kutubxonalar mavjud. Mijoz JavaScript-ni ishlatganda va server Ruby/PHP/Java/nima bo'lganda ham ma'lumotlar almashinuvi uchun JSON-dan foydalanish oson. +======= +The [JSON](https://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation) is a general format to represent values and objects. It is described as in [RFC 4627](https://tools.ietf.org/html/rfc4627) standard. Initially it was made for JavaScript, but many other languages have libraries to handle it as well. So it's easy to use JSON for data exchange when the client uses JavaScript and the server is written on Ruby/PHP/Java/Whatever. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 JavaScript quyidagi usullarni taqdim etadi: @@ -41,7 +45,7 @@ let student = { age: 30, isAdmin: false, courses: ['html', 'css', 'js'], - wife: null + spouse: null }; *!* @@ -58,7 +62,7 @@ alert(json); "age": 30, "isAdmin": false, "courses": ["html", "css", "js"], - "wife": null + "spouse": null } */ */!* @@ -404,7 +408,7 @@ JSON-matnni dekodlash uchun bizga [JSON.parse](mdn:js/JSON/parse) nomli boshqa u Sintaksis: ```js -let value = JSON.parse(str, [reviver]); +let value = JSON.parse(str[, reviver]); ``` str @@ -450,7 +454,11 @@ let json = `{ Bundan tashqari, JSON izohlarni qo'llab-quvvatlamaydi. JSON-ga izoh qo'shish uni bekor qiladi. +<<<<<<< HEAD [JSON5](http://json5.org/) nomli yana bir format mavjud , bu qoshtirnoqsiz kalitlarga, izohlarga va hokazolarga imkon beradi, ammo bu tilning o'ziga xos xususiyatlarida emas, balki mustaqil kutubxona. +======= +There's another format named [JSON5](https://json5.org/), which allows unquoted keys, comments etc. But this is a standalone library, not in the specification of the language. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Oddiy JSON - bu ishlab chiquvchilar dangasa bo'lgani uchun emas, balki tahlil algoritmini oson, ishonchli va juda tez amalga oshirishga imkon berish uchun qat'iydir. diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md index ffa82dd85..06553689e 100644 --- a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md +++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md @@ -37,4 +37,8 @@ P.S. Tabiiyki, formulalar eng tezkor yechimdir. Har qanday `n` raqami uchun atig Tsikl varianti tezligi bo'yicha ikkinchi o'rinda turadi. Rekursiv va tsikl variantida biz bir xil sonlarni qo'shamiz. Ammo rekursiya ichki o'rnatilgan qo'ng'iroqlarni va ijro stekini boshqarishni o'z ichiga oladi. Bu shuningdek resurslarni talab qiladi, shuning uchun bu sekinroq. +<<<<<<< HEAD P.P.S. Standart "quyruq chaqiruvini" optimallashtirishni tavsiflaydi: agar rekursiv chaqiruv funktsiyadagi eng so'nggi (yuqoridagi `sumTo` kabi) bo'lsa, tashqi funktsiya bajarilishini davom ettirishga hojat qolmaydi va biz uning bajarilish konteksti eslashimiz shart emas. Bunday holda `sumTo(100000)` hisoblash mumkin. Ammo agar sizning JavaScript-ni interpretaori qo'llab-quvvatlamasa, unda xato bo'ladi: maksimal to'plam hajmi oshib ketdi, chunki odatda to'plamning umumiy hajmida cheklov mavjud. +======= +P.P.S. Some engines support the "tail call" optimization: if a recursive call is the very last one in the function, with no other calculations performed, then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory. But if the JavaScript engine does not support tail call optimization (most of them don't), there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md index ac2ab4f77..f2ce25851 100644 --- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md +++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md @@ -32,7 +32,11 @@ printReverseList(list); # Tsikldan foydalanish +<<<<<<< HEAD To'g'ridan-to'g'ri chiqishdan ko'ra tsikl varianti biroz murakkabroq. +======= +The loop variant is also a little bit more complicated than the direct output. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bizning `ro'yxatimizdan` oxirgi qiymatni olishning imkoni yo'q. Shuningdek, biz "orqaga qaytishimiz" mumkin emas. diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md index 0c07159f7..021bedc48 100644 --- a/1-js/06-advanced-functions/01-recursion/article.md +++ b/1-js/06-advanced-functions/01-recursion/article.md @@ -61,7 +61,7 @@ Iltimos, rekursiv variant qanday fundamental farq qilishiga e'tibor bering. if n==1 = x / pow(x, n) = - \ + \ else = x * pow(x, n - 1) ``` @@ -275,7 +275,11 @@ Qayta takrorlanadigan `pow` takrorlash jarayonida `i` va `natija` ni o'zgartiril **Har qanday rekursiyani tsikl sifatida qayta yozish mumkin. Tsikl variantini odatda samaraliroq qilish mumkin.** +<<<<<<< HEAD ...Ammo ba'zida qayta yozish ahamiyatsiz bo'ladi, ayniqsa funktsiya sharoitga qarab turli xil rekursiv subchaqiruvlardan foydalanganda va ularning natijalarini birlashtirganda yoki tarmoqlanish murakkabroq bo'lganda. Va optimallashtirish kerak bo'lmasligi va bu umuman harakatlarga loyiq emas bo'lishi mumkin. +======= +...But sometimes the rewrite is non-trivial, especially when a function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Rekursiya kodni qisqartirishi mumkin, uni tushunish va qo'llab-quvvatlash osonroq. Har bir joyda optimallashtirish talab qilinmaydi, asosan bizga yaxshi kod kerak, shuning uchun u ishlatiladi. @@ -522,7 +526,11 @@ Shartlar: list = { value, next -> list } ``` +<<<<<<< HEAD Ushbu bobdagi HTML elementlari daraxti yoki bo'lim daraxti kabi daraxtlar ham tabiiy ravishda rekursivdir: ular shoxlanadi va har bir shox boshqa shoxlarga ega bo'lishi mumkin. +======= + Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they have branches and every branch can have other branches. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Rekursiv funktsiyalar yordamida ularning ustida yurish uchun foydalanish mumkin, buni biz `sumSalary` misolida ko'rdik. diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md index 5253637d7..f51a4f595 100644 --- a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md +++ b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md @@ -24,7 +24,11 @@ function sum(a, b) { alert(sum(1, 2, 3, 4, 5)); ``` +<<<<<<< HEAD "Haddan tashqari" argumentlar tufayli xato bo'lmaydi. Ammo, albatta, natijada faqat dastlabki ikkitasi hisobga olinadi. +======= +There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted, so the result in the code above is `3`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Qoldiq parametrlarni funktsiya ta'rifida uchta nuqta bilan yozish mumkin `...`. Ular so'zma-so'z "qolgan parametrlarni qatorga yig'ish" degan ma'noni anglatadi. diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md index 2089dca96..550a13b57 100644 --- a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md +++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md @@ -1,6 +1,15 @@ +<<<<<<< HEAD # If ning ichidagi funktsiya Kodga qarang. So'nggi satrdagi chaqiruv natijasi qanday bo'ladi? +======= +importance: 5 + +--- +# Function in if + +Look at the code. What will be the result of the call at the last line? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run let phrase = "Hello"; diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js index 74251070f..db6e8e43b 100644 --- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js @@ -22,7 +22,7 @@ describe("byField", function () { { name: "John", age: 20, surname: "Johnson" }, ]; let ageSortedAnswer = users.sort(byField("age")); - assert.deepEqual(ageSortedKey, ageSortedKey); + assert.deepEqual(ageSortedKey, ageSortedAnswer); }); it("sorts users by surname", function () { diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index c7ec27bdb..96f742951 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -8,7 +8,11 @@ Lekin agar funktsiya yaratilgandan so'ng tashqi o'zgaruvchilar o'zgarsa nima bo' Va agar funktsiya argument sifatida uzatilib, kodning boshqa joyidan chaqirilsa, u yangi joydagi tashqi o'zgaruvchilarga kirish huquqiga ega bo'ladimi? +<<<<<<< HEAD Ushbu stsenariylar va yanada murakkab holatlarni tushunish uchun bilimimizni kengaytiraylik. +======= +And what if a function is passed along as an argument and called from another place of code, will it get access to outer variables at the new place? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="Bu yerda `let/const` o'zgaruvchilar haqida gaplashamiz" JavaScript da o'zgaruvchi e'lon qilishning 3 xil usuli bor: `let`, `const` (zamonaviy usullar) va `var` (o'tmishdan qolgan). diff --git a/1-js/06-advanced-functions/04-var/article.md b/1-js/06-advanced-functions/04-var/article.md index 86b3ab178..24675d4dd 100644 --- a/1-js/06-advanced-functions/04-var/article.md +++ b/1-js/06-advanced-functions/04-var/article.md @@ -1,7 +1,17 @@ # Eski "var" +<<<<<<< HEAD [O'zgaruvchanlar](info:variables) haqidagi birinchi bobda biz o'zgaruvchanlarni e'lon qilishning uchta usulini eslatib o'tdik: +======= +```smart header="This article is for understanding old scripts" +The information in this article is useful for understanding old scripts. + +That's not how we write new code. +``` + +In the very first chapter about [variables](info:variables), we mentioned three ways of variable declaration: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 1. `let` 2. `const` @@ -47,7 +57,7 @@ Agar biz 2-satrda `let test` dan foydalansak, u holda `alert` ko'rinmaydi. Ammo Xuddi shu narsa tsiklar uchun: `var` blok-yoki tsikl-lokal bo'lishi mumkin emas: -```js +```js run for (var i = 0; i < 10; i++) { var one = 1; // ... @@ -138,7 +148,7 @@ Buni quyidagi misol bilan namoyish qilish yaxshiroqdir: ```js run function sayHi() { - alert(phrase); + alert(phrase); *!* var phrase = "Salom"; @@ -184,4 +194,77 @@ Yuqoridagi ikkala misolda ham `alert` xatosiz ishlaydi, chunki `phrase` o'zgaruv Global obyekt bilan bog'liq yana bir kichik farq bor, buni keyingi bobda ko'rib chiqamiz. +<<<<<<< HEAD Ushbu farqlar, aslida, ko'pincha yomon narsadir. Blok darajasidagi o'zgaruvchanlar - bu juda yaxshi narsa. Shuning uchun `let` standartga ancha oldin kiritilgan va endi o'zgaruvchanni e'lon qilishning asosiy usuli (`const` bilan birga). +======= +```js run +(function() { + + var message = "Hello"; + + alert(message); // Hello + +})(); +``` + +Here, a Function Expression is created and immediately called. So the code executes right away and has its own private variables. + +The Function Expression is wrapped with parenthesis `(function {...})`, because when JavaScript engine encounters `"function"` in the main code, it understands it as the start of a Function Declaration. But a Function Declaration must have a name, so this kind of code will give an error: + +```js run +// Tries to declare and immediately call a function +function() { // <-- SyntaxError: Function statements require a function name + + var message = "Hello"; + + alert(message); // Hello + +}(); +``` + +Even if we say: "okay, let's add a name", that won't work, as JavaScript does not allow Function Declarations to be called immediately: + +```js run +// syntax error because of parentheses below +function go() { + +}(); // <-- can't call Function Declaration immediately +``` + +So, the parentheses around the function is a trick to show JavaScript that the function is created in the context of another expression, and hence it's a Function Expression: it needs no name and can be called immediately. + +There exist other ways besides parentheses to tell JavaScript that we mean a Function Expression: + +```js run +// Ways to create IIFE + +*!*(*/!*function() { + alert("Parentheses around the function"); +}*!*)*/!*(); + +*!*(*/!*function() { + alert("Parentheses around the whole thing"); +}()*!*)*/!*; + +*!*!*/!*function() { + alert("Bitwise NOT operator starts the expression"); +}(); + +*!*+*/!*function() { + alert("Unary plus starts the expression"); +}(); +``` + +In all the above cases we declare a Function Expression and run it immediately. Let's note again: nowadays there's no reason to write such code. + +## Summary + +There are two main differences of `var` compared to `let/const`: + +1. `var` variables have no block scope, their visibility is scoped to current function, or global, if declared outside function. +2. `var` declarations are processed at function start (script start for globals). + +There's one more very minor difference related to the global object, that we'll cover in the next chapter. + +These differences make `var` worse than `let` most of the time. Block-level variables is such a great thing. That's why `let` was introduced in the standard long ago, and is now a major way (along with `const`) to declare a variable. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/06-advanced-functions/05-global-object/article.md b/1-js/06-advanced-functions/05-global-object/article.md index 64ca03279..70c6b483a 100644 --- a/1-js/06-advanced-functions/05-global-object/article.md +++ b/1-js/06-advanced-functions/05-global-object/article.md @@ -24,7 +24,11 @@ var gVar = 5; alert(window.gVar); // 5 (global objektning xususiyatiga aylandi) ``` +<<<<<<< HEAD Funktsiya e'lonlari ham xuddi shu ta'sirga ega (asosiy kod oqimidagi `function` kalit so'zi bilan iboralar, funktsiya ifodalari emas). +======= +Function declarations have the same effect (statements with `function` keyword in the main code flow, not function expressions). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bunga tayanmang! Bu xatti-harakat moslashish sabablari uchun mavjud. Zamonaviy skriptlar [JavaScript modullari](info:modules)dan foydalanadi, bu yerda bunday narsa sodir bo'lmaydi. diff --git a/1-js/06-advanced-functions/06-function-object/article.md b/1-js/06-advanced-functions/06-function-object/article.md index 0f7008c84..5a4ba67ed 100644 --- a/1-js/06-advanced-functions/06-function-object/article.md +++ b/1-js/06-advanced-functions/06-function-object/article.md @@ -326,7 +326,11 @@ welcome(); // Salom, Mehmon (ichki chaqiruv ishlamoqda) Endi u ishlaydi, chunki `"func"` nomi funktsional-lokal hisoblanadi. U tashqaridan olinmaydi (va u yerda ko'rinmaydi). Spetsifikatsiya har doim mavjud funktsiyaga murojaat qilishiga kafolat beradi. +<<<<<<< HEAD Tashqi kod hali ham `sayHi` yoki `welcome` o'zgaruvchanga ega. Va `func` - bu "ichki funktsiya nomi", funktsiya o'zini o'zi ichkaridan chaqira oladi. +======= +The outer code still has its variable `sayHi` or `welcome`. And `func` is an "internal function name", the way for the function to call itself reliably. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="Funktsiya deklaratsiyasi uchun bunday narsa yo'q" Bu yerda tasvirlangan "ichki ism" xususiyati faqat funktsiya ifodalari uchun mavjud, funktsiya deklaratsiyalari uchun emas. Funktsiya deklaratsiyalari uchun yana bitta "ichki" ism qo'shish uchun sintaksis imkoniyati mavjud emas. diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md index 9ee14ce1b..66bb868d6 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md @@ -27,7 +27,11 @@ Odatda, bu funktsiya. Tarixiy sabablarga ko'ra kod matnni o'tkazish mumkin, ammo : Ishlashdan oldin kechikish, millisekundlarda (1000 ms = 1 soniya), sukut bo'yicha 0. `arg1`, `arg2`... +<<<<<<< HEAD : Funktsiya uchun argumentlar (IE9- da qo'llab-quvvatlanmaydi) +======= +: Arguments for the function +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, ushbu kod bir soniyadan so'ng `sayHi()` ni chaqiradi: @@ -102,7 +106,11 @@ alert(timerId); // bir xil identifikator (bekor qilinganidan keyin null bo'lmayd Shunga qaramay, ushbu usullar uchun universal spetsifikatsiya mavjud emas, shuning uchun hammasi yaxshi. +<<<<<<< HEAD Brauzerlar uchun taymerlar HTML5 standartidagi [taymerlar bo'limida](https://www.w3.org/TR/html5/webappapis.html#timers) tasvirlangan. +======= +For browsers, timers are described in the [timers section](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) of HTML Living Standard. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## setInterval @@ -232,7 +240,11 @@ setTimeout(function() {...}, 100); `setInterval` uchun funktsiya `clearInterval` chaqirilguncha xotirada qoladi. +<<<<<<< HEAD Yon ta'siri bor. Funktsiya tashqi leksik muhitga murojaat qiladi, shuning uchun u yashab turib, tashqi o'zgaruvchanlar ham yashaydi. Ular funktsiyadan ko'ra ko'proq xotirani olishlari mumkin. Shunday qilib, biz endi rejalashtirilgan funktsiyaga muhtoj bo'lmaganda, juda kichik bo'lsa ham, uni bekor qilish yaxshiroqdir. +======= +There's a side effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don't need the scheduled function anymore, it's better to cancel it, even if it's very small. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```` ## Zero delay setTimeout @@ -255,7 +267,12 @@ Birinchi satr "chaqiruvni 0ms dan keyin kalendarga kiritadi". Ammo rejalashtiruv ### CPU vazifalarni ajratish +<<<<<<< HEAD `setTimeout` dan foydalanib, CPU och vazifalarni ajratish uchun hiyla-nayrang bor. +======= +````smart header="Zero delay is in fact not zero (in a browser)" +In the browser, there's a limitation of how often nested timers can run. The [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) says: "after five nested timers, the interval is forced to be at least 4 milliseconds.". +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, sintaksisni ta'kidlaydigan skript (ushbu sahifadagi kod misollarini ranglash uchun ishlatiladi) juda og'ir protsessorga ega. Kodni ajratib ko'rsatish uchun u tahlilni amalga oshiradi, ko'plab rangli elementlarni yaratadi, ularni hujjatga qo'shadi -- ko'p narsalarni talab qiladigan katta matn uchun. Hatto brauzer "osilib qolishi" mumkin, bu esa juda yomon. @@ -390,9 +407,16 @@ Brauzer ichidagi skriptlarning yana bir foydasi shundaki, ular foydalanuvchi uch Shunday qilib, agar biz bitta katta funktsiyani bajaradigan bo'lsak, u biror narsani o'zgartirgan bo'lsa ham, o'zgarishlar tugamaguncha hujjatda aks etmaydi. +<<<<<<< HEAD Mana demo: ```html run
+======= +For example, the in-browser timer may slow down for a lot of reasons: +- The CPU is overloaded. +- The browser tab is in the background mode. +- The laptop is on battery saving mode. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 +======= + + + + + + + WeakRef DOM Logger + + + + +
+ +
+
+

Messages:

+ +
+
+ No messages. +
+
+
+ + + + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js index fc7fe111e..f83eacd15 100644 --- a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js +++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD const startMessagesBtn = document.querySelector(".start-messages"); // (1) const closeWindowBtn = document.querySelector(".window__button"); // (2) const windowElementRef = new WeakRef(document.querySelector(".window__body")); // (3) @@ -27,3 +28,29 @@ const startMessages = (element) => { } }, 1000); }; +======= +const startMessagesBtn = document.querySelector('.start-messages'); // (1) +const closeWindowBtn = document.querySelector('.window__button'); // (2) +const windowElementRef = new WeakRef(document.querySelector(".window__body")); // (3) + +startMessagesBtn.addEventListener('click', () => { // (4) + startMessages(windowElementRef); + startMessagesBtn.disabled = true; +}); + +closeWindowBtn.addEventListener('click', () => document.querySelector(".window__body").remove()); // (5) + + +const startMessages = (element) => { + const timerId = setInterval(() => { // (6) + if (element.deref()) { // (7) + const payload = document.createElement("p"); + payload.textContent = `Message: System status OK: ${new Date().toLocaleTimeString()}`; + element.deref().append(payload); + } else { // (8) + alert("The element has been deleted."); // (9) + clearInterval(timerId); + } + }, 1000); +}; +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css index 206c6b222..c8752df89 100644 --- a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css +++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css @@ -1,4 +1,5 @@ :root { +<<<<<<< HEAD --mineralGreen: 60, 98, 85; --viridianGreen: 97, 135, 110; --swampGreen: 166, 187, 141; @@ -284,3 +285,289 @@ html { .logger--error { background-color: #5a1a24; } +======= + --mineralGreen: 60, 98, 85; + --viridianGreen: 97, 135, 110; + --swampGreen: 166, 187, 141; + --fallGreen: 234, 231, 177; + --brinkPink: #FA7070; + --silverChalice: 178, 178, 178; + --white: 255, 255, 255; + --black: 0, 0, 0; + + --topBarHeight: 64px; + --itemPadding: 32px; + --containerGap: 8px; +} + +@keyframes zoom-in { + 0% { + transform: scale(1, 1); + } + + 100% { + transform: scale(1.30, 1.30); + } +} + +body, html { + margin: 0; + padding: 0; +} + +.app { + min-height: 100vh; + background-color: rgba(var(--viridianGreen), 0.5); +} + +.header { + height: var(--topBarHeight); + padding: 0 24px; + display: flex; + justify-content: space-between; + align-items: center; + background-color: rgba(var(--mineralGreen), 1); +} + +.header-text { + color: white; +} + +.container { + display: flex; + gap: 24px; + padding: var(--itemPadding); +} + +.item { + width: 50%; +} + +.item--scrollable { + overflow-y: scroll; + height: calc(100vh - var(--topBarHeight) - (var(--itemPadding) * 2)); +} + +.thumbnails-container { + display: flex; + flex-wrap: wrap; + gap: 8px; + justify-content: center; + align-items: center; +} + +.thumbnail-item { + width: calc(25% - var(--containerGap)); + cursor: pointer; + position: relative; +} + +.thumbnail-item:hover { + z-index: 1; + animation: zoom-in 0.1s forwards; +} + +.thumbnail-item--selected { + outline: 3px solid rgba(var(--fallGreen), 1); + outline-offset: -3px; +} + +.badge { + width: 16px; + height: 16px; + display: flex; + justify-content: center; + align-items: center; + padding: 4px; + position: absolute; + right: 8px; + bottom: 8px; + border-radius: 50%; + border: 2px solid rgba(var(--fallGreen), 1); + background-color: rgba(var(--swampGreen), 1); +} + +.check { + display: inline-block; + transform: rotate(45deg); + border-bottom: 2px solid white; + border-right: 2px solid white; + width: 6px; + height: 12px; +} + +.img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.actions { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-content: center; + padding: 0 0 16px 0; + gap: 8px; +} + +.select { + padding: 16px; + cursor: pointer; + font-weight: 700; + color: rgba(var(--black), 1); + border: 2px solid rgba(var(--swampGreen), 0.5); + background-color: rgba(var(--swampGreen), 1); +} + +.select:disabled { + cursor: not-allowed; + background-color: rgba(var(--silverChalice), 1); + color: rgba(var(--black), 0.5); + border: 2px solid rgba(var(--black), 0.25); +} + +.btn { + outline: none; + padding: 16px; + cursor: pointer; + font-weight: 700; + color: rgba(var(--black), 1); + border: 2px solid rgba(var(--black), 0.5); +} + +.btn--primary { + background-color: rgba(var(--mineralGreen), 1); +} + +.btn--primary:hover:not([disabled]) { + background-color: rgba(var(--mineralGreen), 0.85); +} + +.btn--secondary { + background-color: rgba(var(--viridianGreen), 0.5); +} + +.btn--secondary:hover:not([disabled]) { + background-color: rgba(var(--swampGreen), 0.25); +} + +.btn--success { + background-color: rgba(var(--fallGreen), 1); +} + +.btn--success:hover:not([disabled]) { + background-color: rgba(var(--fallGreen), 0.85); +} + +.btn:disabled { + cursor: not-allowed; + background-color: rgba(var(--silverChalice), 1); + color: rgba(var(--black), 0.5); + border: 2px solid rgba(var(--black), 0.25); +} + +.previewContainer { + margin-bottom: 16px; + display: flex; + width: 100%; + height: 40vh; + overflow: scroll; + border: 3px solid rgba(var(--black), 1); +} + +.previewContainer--disabled { + background-color: rgba(var(--black), 0.1); + cursor: not-allowed; +} + +.canvas { + margin: auto; + display: none; +} + +.canvas--ready { + display: block; +} + +.spinnerContainer { + display: flex; + gap: 8px; + flex-direction: column; + align-content: center; + align-items: center; + margin: auto; +} + +.spinnerContainer--hidden { + display: none; +} + +.spinnerText { + margin: 0; + color: rgba(var(--mineralGreen), 1); +} + +.spinner { + display: inline-block; + width: 50px; + height: 50px; + margin: auto; + border: 3px solid rgba(var(--mineralGreen), 0.3); + border-radius: 50%; + border-top-color: rgba(var(--mineralGreen), 0.9); + animation: spin 1s ease-in-out infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.loggerContainer { + display: flex; + flex-direction: column; + gap: 8px; + padding: 0 8px 8px 8px; + width: 100%; + min-height: 30vh; + max-height: 30vh; + overflow: scroll; + border-left: 3px solid rgba(var(--black), 0.25); +} + +.logger-title { + display: flex; + align-items: center; + padding: 8px; + position: sticky; + height: 40px; + min-height: 40px; + top: 0; + left: 0; + background-color: rgba(var(--viridianGreen), 1); + font-size: 24px; + font-weight: 700; + margin: 0; +} + +.logger-item { + font-size: 14px; + padding: 8px; + border: 2px solid #5a5a5a; + color: white; +} + +.logger--primary { + background-color: #13315a; +} + +.logger--success { + background-color: #385a4e; +} + +.logger--error { + background-color: #5a1a24; +} +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html index 4ff47160d..9f8b61fa6 100644 --- a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html +++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html @@ -1,3 +1,4 @@ +<<<<<<< HEAD @@ -50,4 +51,54 @@

Foto kutubxona kollaji

+======= + + + + + + + Photo Library Collage + + + + +
+
+

+ Photo Library Collage +

+
+
+
+ +
+
+
+
+
+ + + + +
+
+
+
+

+
+ +
+
+

Logger:

+
+
+
+
+
+ + + + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js index 2b8287ec9..ed9130ef1 100644 --- a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js +++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js @@ -1,4 +1,5 @@ import { +<<<<<<< HEAD createImageFile, loadImage, weakRefCache, @@ -23,6 +24,32 @@ export const state = new Proxy(stateObj, { }); // Elementlar. +======= + createImageFile, + loadImage, + weakRefCache, + LAYOUTS, + images, + THUMBNAIL_PARAMS, + stateObj, +} from "./utils.js"; + +export const state = new Proxy(stateObj, { + set(target, property, value) { + const previousValue = target[property]; + + target[property] = value; + + if (previousValue !== value) { + handleStateChange(target); + } + + return true; + }, +}); + +// Elements. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 const thumbnailsContainerEl = document.querySelector(".thumbnails-container"); const selectEl = document.querySelector(".select"); const previewContainerEl = document.querySelector(".previewContainer"); @@ -34,6 +61,7 @@ const spinnerContainerEl = document.querySelector(".spinnerContainer"); const spinnerTextEl = document.querySelector(".spinnerText"); const loggerContainerEl = document.querySelector(".loggerContainer"); +<<<<<<< HEAD // Renderlar. // Thumbnail ko'rinishlarini render qilish. images.forEach((img) => { @@ -88,10 +116,67 @@ const handleStateChange = (state) => { } else if (state.collageRendered) { downloadBtn.disabled = false; } +======= +// Renders. +// Render thumbnails previews. +images.forEach((img) => { + const thumbnail = document.createElement("div"); + thumbnail.classList.add("thumbnail-item"); + + thumbnail.innerHTML = ` + + `; + + thumbnail.addEventListener("click", (e) => handleSelection(e, img)); + + thumbnailsContainerEl.appendChild(thumbnail); +}); +// Render layouts select. +LAYOUTS.forEach((layout) => { + const option = document.createElement("option"); + option.value = JSON.stringify(layout); + option.innerHTML = layout.name; + selectEl.appendChild(option); +}); + +const handleStateChange = (state) => { + if (state.loading) { + selectEl.disabled = true; + createCollageBtn.disabled = true; + startOverBtn.disabled = true; + downloadBtn.disabled = true; + previewContainerEl.classList.add("previewContainer--disabled"); + spinnerContainerEl.classList.remove("spinnerContainer--hidden"); + spinnerTextEl.innerText = "Loading..."; + canvasEl.classList.remove("canvas--ready"); + } else if (!state.loading) { + selectEl.disabled = false; + createCollageBtn.disabled = false; + startOverBtn.disabled = false; + downloadBtn.disabled = false; + previewContainerEl.classList.remove("previewContainer--disabled"); + spinnerContainerEl.classList.add("spinnerContainer--hidden"); + canvasEl.classList.add("canvas--ready"); + } + + if (!state.selectedImages.size) { + createCollageBtn.disabled = true; + document.querySelectorAll(".badge").forEach((item) => item.remove()); + } else if (state.selectedImages.size && !state.loading) { + createCollageBtn.disabled = false; + } + + if (!state.collageRendered) { + downloadBtn.disabled = true; + } else if (state.collageRendered) { + downloadBtn.disabled = false; + } +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 }; handleStateChange(state); const handleSelection = (e, imgName) => { +<<<<<<< HEAD const imgEl = e.currentTarget; imgEl.classList.toggle("thumbnail-item--selected"); @@ -222,6 +307,138 @@ const changeLayout = ({ target }) => { }; // Tinglovchilar. +======= + const imgEl = e.currentTarget; + + imgEl.classList.toggle("thumbnail-item--selected"); + + if (state.selectedImages.has(imgName)) { + state.selectedImages.delete(imgName); + state.selectedImages = new Set(state.selectedImages); + imgEl.querySelector(".badge")?.remove(); + } else { + state.selectedImages = new Set(state.selectedImages.add(imgName)); + + const badge = document.createElement("div"); + badge.classList.add("badge"); + badge.innerHTML = ` +
+ `; + imgEl.prepend(badge); + } +}; + +// Make a wrapper function. +let getCachedImage; +(async () => { + getCachedImage = await weakRefCache(loadImage); +})(); + +const calculateGridRows = (blobsLength) => + Math.ceil(blobsLength / state.currentLayout.columns); + +const drawCollage = (images) => { + state.drawing = true; + + let context = canvasEl.getContext("2d"); + + /** + * Calculate canvas dimensions based on the current layout. + * */ + context.canvas.width = + state.currentLayout.itemWidth * state.currentLayout.columns; + context.canvas.height = + calculateGridRows(images.length) * state.currentLayout.itemHeight; + + let currentRow = 0; + let currentCanvasDx = 0; + let currentCanvasDy = 0; + + for (let i = 0; i < images.length; i++) { + /** + * Get current row of the collage. + * */ + if (i % state.currentLayout.columns === 0) { + currentRow += 1; + currentCanvasDx = 0; + + if (currentRow > 1) { + currentCanvasDy += state.currentLayout.itemHeight; + } + } + + context.drawImage( + images[i], + 0, + 0, + images[i].width, + images[i].height, + currentCanvasDx, + currentCanvasDy, + state.currentLayout.itemWidth, + state.currentLayout.itemHeight, + ); + + currentCanvasDx += state.currentLayout.itemWidth; + } + + state.drawing = false; + state.collageRendered = true; +}; + +const createCollage = async () => { + state.loading = true; + + const images = []; + + for (const image of state.selectedImages.values()) { + const blobImage = await getCachedImage(image.img); + + const url = URL.createObjectURL(blobImage); + const img = await createImageFile(url); + + images.push(img); + URL.revokeObjectURL(url); + } + + state.loading = false; + + drawCollage(images); +}; + +/** + * Clear all settled data to start over. + * */ +const startOver = () => { + state.selectedImages = new Set(); + state.collageRendered = false; + const context = canvasEl.getContext("2d"); + context.clearRect(0, 0, canvasEl.width, canvasEl.height); + + document + .querySelectorAll(".thumbnail-item--selected") + .forEach((item) => item.classList.remove("thumbnail-item--selected")); + + loggerContainerEl.innerHTML = '

Logger:

'; +}; + +const downloadCollage = () => { + const date = new Date(); + const fileName = `Collage-${date.getDay()}-${date.getMonth()}-${date.getFullYear()}.png`; + const img = canvasEl.toDataURL("image/png"); + const link = document.createElement("a"); + link.download = fileName; + link.href = img; + link.click(); + link.remove(); +}; + +const changeLayout = ({ target }) => { + state.currentLayout = JSON.parse(target.value); +}; + +// Listeners. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 selectEl.addEventListener("change", changeLayout); createCollageBtn.addEventListener("click", createCollage); startOverBtn.addEventListener("click", startOver); diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js index c10b4fe70..3ba9d6463 100644 --- a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js +++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js @@ -1,6 +1,7 @@ const loggerContainerEl = document.querySelector(".loggerContainer"); export const images = [ +<<<<<<< HEAD { img: "https://images.unsplash.com/photo-1471357674240-e1a485acb3e1", }, @@ -193,11 +194,206 @@ export const images = [ { img: "https://images.unsplash.com/photo-1528759335187-3b683174c86a", }, +======= + { + img: "https://images.unsplash.com/photo-1471357674240-e1a485acb3e1", + }, + { + img: "https://images.unsplash.com/photo-1589118949245-7d38baf380d6", + }, + { + img: "https://images.unsplash.com/photo-1527631746610-bca00a040d60", + }, + { + img: "https://images.unsplash.com/photo-1500835556837-99ac94a94552", + }, + { + img: "https://images.unsplash.com/photo-1503220317375-aaad61436b1b", + }, + { + img: "https://images.unsplash.com/photo-1501785888041-af3ef285b470", + }, + { + img: "https://images.unsplash.com/photo-1528543606781-2f6e6857f318", + }, + { + img: "https://images.unsplash.com/photo-1523906834658-6e24ef2386f9", + }, + { + img: "https://images.unsplash.com/photo-1539635278303-d4002c07eae3", + }, + { + img: "https://images.unsplash.com/photo-1533105079780-92b9be482077", + }, + { + img: "https://images.unsplash.com/photo-1516483638261-f4dbaf036963", + }, + { + img: "https://images.unsplash.com/photo-1502791451862-7bd8c1df43a7", + }, + { + img: "https://plus.unsplash.com/premium_photo-1663047367140-91adf819d007", + }, + { + img: "https://images.unsplash.com/photo-1506197603052-3cc9c3a201bd", + }, + { + img: "https://images.unsplash.com/photo-1517760444937-f6397edcbbcd", + }, + { + img: "https://images.unsplash.com/photo-1518684079-3c830dcef090", + }, + { + img: "https://images.unsplash.com/photo-1505832018823-50331d70d237", + }, + { + img: "https://images.unsplash.com/photo-1524850011238-e3d235c7d4c9", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661277758451-b5053309eea1", + }, + { + img: "https://images.unsplash.com/photo-1541410965313-d53b3c16ef17", + }, + { + img: "https://images.unsplash.com/photo-1528702748617-c64d49f918af", + }, + { + img: "https://images.unsplash.com/photo-1502003148287-a82ef80a6abc", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661281272544-5204ea3a481a", + }, + { + img: "https://images.unsplash.com/photo-1503457574462-bd27054394c1", + }, + { + img: "https://images.unsplash.com/photo-1499363536502-87642509e31b", + }, + { + img: "https://images.unsplash.com/photo-1551918120-9739cb430c6d", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661382219642-43e54f7e81d7", + }, + { + img: "https://images.unsplash.com/photo-1497262693247-aa258f96c4f5", + }, + { + img: "https://images.unsplash.com/photo-1525254134158-4fd5fdd45793", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661274025419-4c54107d5c48", + }, + { + img: "https://images.unsplash.com/photo-1553697388-94e804e2f0f6", + }, + { + img: "https://images.unsplash.com/photo-1574260031597-bcd9eb192b4f", + }, + { + img: "https://images.unsplash.com/photo-1536323760109-ca8c07450053", + }, + { + img: "https://images.unsplash.com/photo-1527824404775-dce343118ebc", + }, + { + img: "https://images.unsplash.com/photo-1612278675615-7b093b07772d", + }, + { + img: "https://images.unsplash.com/photo-1522010675502-c7b3888985f6", + }, + { + img: "https://images.unsplash.com/photo-1501555088652-021faa106b9b", + }, + { + img: "https://plus.unsplash.com/premium_photo-1669223469435-27e091439169", + }, + { + img: "https://images.unsplash.com/photo-1506012787146-f92b2d7d6d96", + }, + { + img: "https://images.unsplash.com/photo-1511739001486-6bfe10ce785f", + }, + { + img: "https://images.unsplash.com/photo-1553342385-111fd6bc6ab3", + }, + { + img: "https://images.unsplash.com/photo-1516546453174-5e1098a4b4af", + }, + { + img: "https://images.unsplash.com/photo-1527142879-95b61a0b8226", + }, + { + img: "https://images.unsplash.com/photo-1520466809213-7b9a56adcd45", + }, + { + img: "https://images.unsplash.com/photo-1516939884455-1445c8652f83", + }, + { + img: "https://images.unsplash.com/photo-1545389336-cf090694435e", + }, + { + img: "https://plus.unsplash.com/premium_photo-1669223469455-b7b734c838f4", + }, + { + img: "https://images.unsplash.com/photo-1454391304352-2bf4678b1a7a", + }, + { + img: "https://images.unsplash.com/photo-1433838552652-f9a46b332c40", + }, + { + img: "https://images.unsplash.com/photo-1506125840744-167167210587", + }, + { + img: "https://images.unsplash.com/photo-1522199873717-bc67b1a5e32b", + }, + { + img: "https://images.unsplash.com/photo-1495904786722-d2b5a19a8535", + }, + { + img: "https://images.unsplash.com/photo-1614094082869-cd4e4b2905c7", + }, + { + img: "https://images.unsplash.com/photo-1474755032398-4b0ed3b2ae5c", + }, + { + img: "https://images.unsplash.com/photo-1501554728187-ce583db33af7", + }, + { + img: "https://images.unsplash.com/photo-1515859005217-8a1f08870f59", + }, + { + img: "https://images.unsplash.com/photo-1531141445733-14c2eb7d4c1f", + }, + { + img: "https://images.unsplash.com/photo-1500259783852-0ca9ce8a64dc", + }, + { + img: "https://images.unsplash.com/photo-1510662145379-13537db782dc", + }, + { + img: "https://images.unsplash.com/photo-1573790387438-4da905039392", + }, + { + img: "https://images.unsplash.com/photo-1512757776214-26d36777b513", + }, + { + img: "https://images.unsplash.com/photo-1518855706573-84de4022b69b", + }, + { + img: "https://images.unsplash.com/photo-1500049242364-5f500807cdd7", + }, + { + img: "https://images.unsplash.com/photo-1528759335187-3b683174c86a", + }, +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ]; export const THUMBNAIL_PARAMS = "w=240&h=240&fit=crop&auto=format"; // Console styles. export const CONSOLE_BASE_STYLES = [ +<<<<<<< HEAD "font-size: 12px", "padding: 4px", "border: 2px solid #5a5a5a", @@ -214,10 +410,29 @@ export const CONSOLE_SUCCESS = [ export const CONSOLE_ERROR = [ CONSOLE_BASE_STYLES, "background-color: #5a1a24", +======= + "font-size: 12px", + "padding: 4px", + "border: 2px solid #5a5a5a", + "color: white", +].join(";"); +export const CONSOLE_PRIMARY = [ + CONSOLE_BASE_STYLES, + "background-color: #13315a", +].join(";"); +export const CONSOLE_SUCCESS = [ + CONSOLE_BASE_STYLES, + "background-color: #385a4e", +].join(";"); +export const CONSOLE_ERROR = [ + CONSOLE_BASE_STYLES, + "background-color: #5a1a24", +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ].join(";"); // Layouts. export const LAYOUT_4_COLUMNS = { +<<<<<<< HEAD name: "Layout 4 columns", columns: 4, itemWidth: 240, @@ -228,10 +443,23 @@ export const LAYOUT_8_COLUMNS = { columns: 8, itemWidth: 240, itemHeight: 240, +======= + name: "Layout 4 columns", + columns: 4, + itemWidth: 240, + itemHeight: 240, +}; +export const LAYOUT_8_COLUMNS = { + name: "Layout 8 columns", + columns: 8, + itemWidth: 240, + itemHeight: 240, +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 }; export const LAYOUTS = [LAYOUT_4_COLUMNS, LAYOUT_8_COLUMNS]; export const createImageFile = async (src) => +<<<<<<< HEAD new Promise((resolve, reject) => { const img = new Image(); img.src = src; @@ -318,4 +546,92 @@ export const stateObj = { collageRendered: false, currentLayout: LAYOUTS[0], selectedImages: new Set(), +======= + new Promise((resolve, reject) => { + const img = new Image(); + img.src = src; + img.onload = () => resolve(img); + img.onerror = () => reject(new Error("Failed to construct image.")); + }); + +export const loadImage = async (url) => { + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error(String(response.status)); + } + + return await response.blob(); + } catch (e) { + console.log(`%cFETCHED_FAILED: ${e}`, CONSOLE_ERROR); + } +}; + +export const weakRefCache = (fetchImg) => { + const imgCache = new Map(); + const registry = new FinalizationRegistry(({ imgName, size, type }) => { + const cachedImg = imgCache.get(imgName); + if (cachedImg && !cachedImg.deref()) { + imgCache.delete(imgName); + console.log( + `%cCLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`, + CONSOLE_ERROR, + ); + + const logEl = document.createElement("div"); + logEl.classList.add("logger-item", "logger--error"); + logEl.innerHTML = `CLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`; + loggerContainerEl.appendChild(logEl); + loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight; + } + }); + + return async (imgName) => { + const cachedImg = imgCache.get(imgName); + + if (cachedImg?.deref() !== undefined) { + console.log( + `%cCACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`, + CONSOLE_SUCCESS, + ); + + const logEl = document.createElement("div"); + logEl.classList.add("logger-item", "logger--success"); + logEl.innerHTML = `CACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`; + loggerContainerEl.appendChild(logEl); + loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight; + + return cachedImg?.deref(); + } + + const newImg = await fetchImg(imgName); + console.log( + `%cFETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`, + CONSOLE_PRIMARY, + ); + + const logEl = document.createElement("div"); + logEl.classList.add("logger-item", "logger--primary"); + logEl.innerHTML = `FETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`; + loggerContainerEl.appendChild(logEl); + loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight; + + imgCache.set(imgName, new WeakRef(newImg)); + registry.register(newImg, { + imgName, + size: newImg.size, + type: newImg.type, + }); + + return newImg; + }; +}; + +export const stateObj = { + loading: false, + drawing: true, + collageRendered: false, + currentLayout: LAYOUTS[0], + selectedImages: new Set(), +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 }; diff --git a/2-ui/1-document/01-browser-environment/article.md b/2-ui/1-document/01-browser-environment/article.md index a2681b646..2887b47fb 100644 --- a/2-ui/1-document/01-browser-environment/article.md +++ b/2-ui/1-document/01-browser-environment/article.md @@ -1,10 +1,18 @@ # Brauzer muhiti, xususiyatlari +<<<<<<< HEAD JavaScript tili dastlab veb-brauzerlar uchun yaratilgan. O'shandan beri u rivojlanib, ko'plab foydalanish va platformalarga ega tilga aylandi. Platforma JavaScript-ni ishga tushira olsa, brauzer yoki veb-server yoki boshqa _host_, hatto "aqlli" qahva mashinasi bo'lishi mumkin. Ularning har biri platformaga xos funksiyalarni taqdim etadi. JavaScript spetsifikatsiyasi buni _host muhiti_ deb ataydi. Xost muhiti til yadrosiga qo'shimcha ravishda o'z ob'ektlari va funktsiyalarini ta'minlaydi. Veb-brauzerlar veb-sahifalarni boshqarish vositalarini beradi. Node.js server tomonidagi xususiyatlarni taqdim etadi va hokazo. +======= +The JavaScript language was initially created for web browsers. Since then, it has evolved into a language with many uses and platforms. + +A platform may be a browser, or a web-server or another *host*, or even a "smart" coffee machine if it can run JavaScript. Each of these provides platform-specific functionality. The JavaScript specification calls that a *host environment*. + +A host environment provides its own objects and functions in addition to the language core. Web browsers give a means to control web pages. Node.js provides server-side features, and so on. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 JavaScript veb-brauzerda ishlayotganida bizda nima borligini qushning nazari bilan ko'rib chiqamiz: @@ -15,9 +23,13 @@ JavaScript veb-brauzerda ishlayotganida bizda nima borligini qushning nazari bil 1. Birinchidan, bu bobida tasvirlanganidek, JavaScript kodi uchun global obyektdir. 2. Ikkinchidan, u "brauzer oynasi" ni ifodalaydi va uni boshqarish usullarini taqdim etadi. +<<<<<<< HEAD Masalan, biz uni global ob'ekt sifatida ishlatamiz: +======= +For instance, we can use it as a global object: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 -```js run +```js run global function sayHi() { alert("Hello"); } @@ -26,17 +38,29 @@ function sayHi() { window.sayHi(); ``` +<<<<<<< HEAD Va bu erda biz uni brauzer oynasi sifatida ishlatamiz, oyna balandligini ko'rish uchun: +======= +And we can use it as a browser window, to show the window height: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js run alert(window.innerHeight); // oynaning ichki balandligi ``` +<<<<<<< HEAD Ko'proq oynaga xos usullar va xususiyatlar mavjud, biz ularni keyinroq ko'rib chiqamiz. ## DOM (Document Object Model) Hujjat ob'ekt modeli yoki qisqacha DOM barcha sahifa mazmunini o'zgartirish mumkin bo'lgan ob'ektlar sifatida ifodalaydi. +======= +There are more window-specific methods and properties, which we'll cover later. + +## DOM (Document Object Model) + +The Document Object Model, or DOM for short, represents all page content as objects that can be modified. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `Hujjat` ob'ekti sahifaning asosiy "kirish nuqtasi" hisoblanadi. Uning yordamida biz sahifadagi biror narsani o'zgartirishimiz yoki yaratishimiz mumkin. @@ -50,18 +74,30 @@ document.body.style.background = "red"; setTimeout(() => (document.body.style.background = ""), 1000); ``` +<<<<<<< HEAD Bu erda biz `document.body.style` dan foydalandik, lekin yana ko'p narsalar bor. Xususiyatlar va usullar spetsifikatsiyada tasvirlangan: [DOM Living Standard](https://dom.spec.whatwg.org). +======= +Here, we used `document.body.style`, but there's much, much more. Properties and methods are described in the specification: [DOM Living Standard](https://dom.spec.whatwg.org). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="DOM faqat brauzerlar uchun emas" DOM spetsifikatsiyasi hujjatning tuzilishini tushuntiradi va uni boshqarish uchun ob'ektlarni taqdim etadi. DOM-dan foydalanadigan brauzer bo'lmagan asboblar ham mavjud. +<<<<<<< HEAD Masalan, HTML-sahifalarni yuklaydigan va ularni qayta ishlovchi server tomonidagi skriptlar ham DOM-dan foydalanishi mumkin. Ular spetsifikatsiyaning faqat bir qismini qo'llab-quvvatlashi mumkin. +======= +For instance, server-side scripts that download HTML pages and process them can also use the DOM. They may support only a part of the specification though. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ```smart header="Styling uchun CSSOM" Shuningdek, CSS qoidalari va uslublar jadvallari uchun [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/) alohida spetsifikatsiya mavjud bo'lib, ular qanday ob'ektlar sifatida taqdim etilishini, ularni qanday o'qish va yozishni tushuntiradi. +<<<<<<< HEAD Hujjat uchun uslub qoidalarini o'zgartirganda CSSOM DOM bilan birgalikda ishlatiladi. Amalda, CSSOM kamdan-kam talab qilinadi, chunki biz kamdan-kam hollarda JavaScript-dan CSS qoidalarini o'zgartirishimiz kerak (odatda biz CSS sinflarini qo'shamiz/o'chiramiz, ularning CSS qoidalarini o'zgartirmaymiz), lekin bu ham mumkin. +======= +The CSSOM is used together with the DOM when we modify style rules for the document. In practice though, the CSSOM is rarely required, because we rarely need to modify CSS rules from JavaScript (usually we just add/remove CSS classes, not modify their CSS rules), but that's also possible. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## BOM (Browser Object Model) @@ -70,8 +106,13 @@ Brauzer ob'ekt modeli (BOM) hujjatdan tashqari hamma narsa bilan ishlash uchun b Masalan: +<<<<<<< HEAD - [navigator](mdn:api/Window/navigator) obyekti brauzer va operatsion tizim haqida fon maʼlumotlarini taqdim etadi. Ko'pgina xususiyatlar mavjud, lekin eng ko'p ma'lum bo'lgan ikkitasi: `navigator.userAgent` -- joriy brauzer haqida va `navigator.platform` -- platforma haqida (Windows/Linux/Mac va boshqalar o'rtasidagi farqni aniqlashga yordam beradi). - [location](mdn:api/Window/location) obyekti bizga joriy URL manzilini o‘qish imkonini beradi va brauzerni yangisiga yo‘naltirishi mumkin. +======= +- The [navigator](mdn:api/Window/navigator) object provides background information about the browser and the operating system. There are many properties, but the two most widely known are: `navigator.userAgent` -- about the current browser, and `navigator.platform` -- about the platform (can help to differentiate between Windows/Linux/Mac etc). +- The [location](mdn:api/Window/location) object allows us to read the current URL and can redirect the browser to a new one. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `location` obyektidan shunday foydalanishimiz mumkin: @@ -82,33 +123,60 @@ if (confirm("Go to Wikipedia?")) { } ``` +<<<<<<< HEAD `alert/confirm/prompt` funksiyalari ham BOMning bir qismidir: ular hujjat bilan bevosita bog'liq emas, lekin foydalanuvchi bilan muloqot qilishning sof brauzer usullarini ifodalaydi. ```smart header="Xususiyatlar" BOM umumiy [HTML spetsifikatsiyasi] (https://html.spec.whatwg.org) qismidir. Ha, siz buni to'g'ri eshitdingiz. saytidagi HTML spetsifikatsiyasi nafaqat "HTML tili" (teglar, atributlar), balki bir qator ob'ektlar, usullar va brauzerga xos DOM kengaytmalarini ham qamrab oladi. Bu "keng ma'noda HTML". Shuningdek, ba'zi qismlarda ro'yxatida qo'shimcha xususiyatlar mavjud. +======= +The functions `alert/confirm/prompt` are also a part of the BOM: they are not directly related to the document, but represent pure browser methods for communicating with the user. + +```smart header="Specifications" +The BOM is a part of the general [HTML specification](https://html.spec.whatwg.org). + +Yes, you heard that right. The HTML spec at is not only about the "HTML language" (tags, attributes), but also covers a bunch of objects, methods, and browser-specific DOM extensions. That's "HTML in broad terms". Also, some parts have additional specs listed at . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Xulosa Standartlar haqida gapiradigan bo'lsak, bizda: +<<<<<<< HEAD DOM spetsifikatsiyasi : Hujjat tuzilishi, manipulyatsiyalar va hodisalarni tavsiflaydi, qarang: . CSSOM spetsifikatsiyasi : Uslublar jadvallari va uslublar qoidalarini, ular bilan manipulyatsiyalarni va ularni hujjatlarga bog'lashni tavsiflaydi, qarang: . +======= +DOM specification +: Describes the document structure, manipulations, and events, see . + +CSSOM specification +: Describes stylesheets and style rules, manipulations with them, and their binding to documents, see . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 HTML spetsifikatsiyasi : HTML tilini (masalan, teglar) va shuningdek, BOMni (brauzer ob'ekt modeli) tavsiflaydi -- turli xil brauzer funktsiyalari: `setTimeout`, `alert`, `location` va boshqalar, qarang: . U DOM spetsifikatsiyasini oladi va uni ko'plab qo'shimcha xususiyatlar va usullar bilan kengaytiradi. Bundan tashqari, ba'zi sinflar da alohida tasvirlangan. +<<<<<<< HEAD Iltimos, ushbu havolalarga e'tibor bering, chunki o'rganish uchun juda ko'p narsa bor, hamma narsani qamrab olish va eslab qolish mumkin emas. Xususiyat yoki usul haqida oʻqishni istasangiz, sahifasidagi Mozilla qoʻllanmasi ham yaxshi manba boʻlib xizmat qiladi, ammo mos keladigan xususiyat yaxshiroq boʻlishi mumkin: u murakkabroq va oʻqish uchun uzoqroq, lekin asosiy bilimlaringizni mustahkam va toʻliq qiladi. +======= +Please note these links, as there's so much to learn that it's impossible to cover everything and remember it all. + +When you'd like to read about a property or a method, the Mozilla manual at is also a nice resource, but the corresponding spec may be better: it's more complex and longer to read, but will make your fundamental knowledge sound and complete. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biror narsani topish uchun "WHATWG [term]" yoki "MDN [term]" kabi internet qidiruvidan foydalanish qulay, masalan, , . +<<<<<<< HEAD Endi biz DOMni o'rganishga kirishamiz, chunki hujjat UIda markaziy rol o'ynaydi. +======= +Now, we'll get down to learning the DOM, because the document plays the central role in the UI. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/2-ui/1-document/02-dom-nodes/article.md b/2-ui/1-document/02-dom-nodes/article.md index 2eb55eda8..cfb64cc95 100644 --- a/2-ui/1-document/02-dom-nodes/article.md +++ b/2-ui/1-document/02-dom-nodes/article.md @@ -51,7 +51,11 @@ DOM HTML ni teglarning daraxt tuzilishi sifatida ifodalaydi. Qanday ko'rinishi:
@@ -211,7 +215,11 @@ Butun hujjatni ifodalovchi `document` obyekti ham rasman DOM tuguni hisoblanadi. ## O'zingiz ko'ring +<<<<<<< HEAD DOM tuzilishini real vaqtda ko'rish uchun [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/) ni sinab ko'ring. Shunchaki hujjatni yozing va u bir zumda DOM sifatida ko'rsatiladi. +======= +To see the DOM structure in real-time, try [Live DOM Viewer](https://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up as a DOM at an instant. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 DOM ni o'rganishning boshqa usuli - brauzer dasturchi vositalaridan foydalanish. Aslida, biz rivojlanishda shu usuldan foydalanamiz. diff --git a/2-ui/1-document/04-searching-elements-dom/article.md b/2-ui/1-document/04-searching-elements-dom/article.md index 260adf839..355f75d41 100644 --- a/2-ui/1-document/04-searching-elements-dom/article.md +++ b/2-ui/1-document/04-searching-elements-dom/article.md @@ -60,8 +60,13 @@ Shuningdek, `id` nomi bilan global o'zgaruvchi mavjud bo'lib, u elementga havola ``` +<<<<<<< HEAD ```warn header="Elementlarga murojaat qilish uchun id nomli global o'zgaruvchilardan foydalanmang" Bu xatti-harakat [spetsifikatsiyada](http://www.whatwg.org/specs/web-apps/current-work/#dom-window-nameditem) tasvirlangan, shuning uchun bu standart hisoblanadi. Lekin u asosan muvofiqlik uchun qo'llab-quvvatlanadi. +======= +```warn header="Please don't use id-named global variables to access elements" +This behavior is described [in the specification](https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object), but it is supported mainly for compatibility. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Brauzer JS va DOM nomlar maydonlarini aralashtirish orqali bizga yordam berishga harakat qiladi. Bu HTML ga kiritilgan oddiy skriptlar uchun yaxshi, lekin umuman yaxshi narsa emas. Nom to'qnashuvi bo'lishi mumkin. Bundan tashqari, kimdir JS kodini o'qiganda va HTML ko'rinishda bo'lmasa, o'zgaruvchi qayerdan kelganini bilish qiyin. @@ -122,7 +127,11 @@ Boshqacha qilib aytganda, natija `elem.querySelectorAll(css)[0]` bilan bir xil, Oldingi metodlar DOM ni qidirardi. +<<<<<<< HEAD [elem.matches(css)](http://dom.spec.whatwg.org/#dom-element-matches) hech narsani qidirmaydi, u shunchaki `elem` berilgan CSS-selektorga mos kelishini tekshiradi. U `true` yoki `false` qaytaradi. +======= +The [elem.matches(css)](https://dom.spec.whatwg.org/#dom-element-matches) does not look for anything, it merely checks if `elem` matches the given CSS-selector. It returns `true` or `false`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu metod elementlar ustida takrorlash (massivdagi kabi yoki boshqa narsa) va bizni qiziqtiradigan narsalarni filtrlashga harakat qilganda foydali bo'ladi. @@ -159,8 +168,13 @@ Masalan:
    +<<<<<<< HEAD
  • 1-bob
  • 2-bob
  • +======= +
  • Chapter 1
  • +
  • Chapter 2
  • +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19
diff --git a/2-ui/1-document/05-basic-dom-node-properties/article.md b/2-ui/1-document/05-basic-dom-node-properties/article.md index e747cb3e0..93329e5fa 100644 --- a/2-ui/1-document/05-basic-dom-node-properties/article.md +++ b/2-ui/1-document/05-basic-dom-node-properties/article.md @@ -14,7 +14,11 @@ Ushbu bobda biz ular nima ekanligini ko'rib chiqamiz va eng ko'p ishlatiladigan Turli DOM tugunlari turli xususiyatlarga ega bo'lishi mumkin. Masalan, `` tegiga mos keladigan element tuguni havola bilan bog'liq xususiyatlarga ega, `` ga mos keluvchisi esa input bilan bog'liq xususiyatlarga ega va hokazo. Matn tugunlari element tugunlari bilan bir xil emas. Lekin ular orasida umumiy xususiyatlar va metodlar ham mavjud, chunki barcha DOM tugun klasslari yagona ierarxiyani tashkil qiladi. +<<<<<<< HEAD Har bir DOM tuguni tegishli o'rnatilgan klassga tegishli. +======= +The root of the hierarchy is [EventTarget](https://dom.spec.whatwg.org/#eventtarget), that is inherited by [Node](https://dom.spec.whatwg.org/#interface-node), and other DOM nodes inherit from it. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ierarxiyaning ildizi [EventTarget](https://dom.spec.whatwg.org/#eventtarget) bo'lib, undan [Node](http://dom.spec.whatwg.org/#interface-node) meros oladi va boshqa DOM tugunlari undan meros oladi. @@ -24,6 +28,7 @@ Mana rasm, tushuntirishlar keyinroq: Klasslar: +<<<<<<< HEAD - [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- ildiz "mavhum" klass. Bu klassning obyektlari hech qachon yaratilmaydi. U asos bo'lib xizmat qiladi, shunda barcha DOM tugunlari "hodisalar" deb ataladigan narsani qo'llab-quvvatlaydi, biz ularni keyinroq o'rganamiz. - [Node](http://dom.spec.whatwg.org/#interface-node) -- bu ham "mavhum" klass bo'lib, DOM tugunlari uchun asos bo'lib xizmat qiladi. U asosiy daraxt funksionalligini taqdim etadi: `parentNode`, `nextSibling`, `childNodes` va hokazo (bular getter'lardir). `Node` klassining obyektlari hech qachon yaratilmaydi. Lekin undan meros oladigan aniq tugun klasslari mavjud, ya'ni: matn tugunlari uchun `Text`, element tugunlari uchun `Element` va izoh tugunlari uchun `Comment` kabi boshqa ekzotik klasslar. - [Element](http://dom.spec.whatwg.org/#interface-element) -- DOM elementlari uchun asos klass. U element darajasidagi navigatsiyani taqdim etadi, masalan `nextElementSibling`, `children` va `getElementsByTagName`, `querySelector` kabi qidiruv metodlari. Brauzer nafaqat HTML, balki XML va SVG ni ham qo'llab-quvvatlaydi. `Element` klassi aniqroq klasslar uchun asos bo'lib xizmat qiladi: `SVGElement`, `XMLElement` va `HTMLElement`. @@ -34,6 +39,41 @@ Klasslar: - ...va hokazo, har bir tegning aniq xususiyatlar va metodlarni taqdim etishi mumkin bo'lgan o'z klassi bor. Shunday qilib, berilgan tugunning barcha xususiyatlar va metodlari to'plami merosxo'rlik natijasida hosil bo'ladi. +======= +- [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- is the root "abstract" class for everything. + + Objects of that class are never created. It serves as a base, so that all DOM nodes support so-called "events", we'll study them later. + +- [Node](https://dom.spec.whatwg.org/#interface-node) -- is also an "abstract" class, serving as a base for DOM nodes. + + It provides the core tree functionality: `parentNode`, `nextSibling`, `childNodes` and so on (they are getters). Objects of `Node` class are never created. But there are other classes that inherit from it (and so inherit the `Node` functionality). + +- [Document](https://dom.spec.whatwg.org/#interface-document), for historical reasons often inherited by `HTMLDocument` (though the latest spec doesn't dictate it) -- is a document as a whole. + + The `document` global object belongs exactly to this class. It serves as an entry point to the DOM. + +- [CharacterData](https://dom.spec.whatwg.org/#interface-characterdata) -- an "abstract" class, inherited by: + - [Text](https://dom.spec.whatwg.org/#interface-text) -- the class corresponding to a text inside elements, e.g. `Hello` in `

Hello

`. + - [Comment](https://dom.spec.whatwg.org/#interface-comment) -- the class for comments. They are not shown, but each comment becomes a member of DOM. + +- [Element](https://dom.spec.whatwg.org/#interface-element) -- is the base class for DOM elements. + + It provides element-level navigation like `nextElementSibling`, `children` and searching methods like `getElementsByTagName`, `querySelector`. + + A browser supports not only HTML, but also XML and SVG. So the `Element` class serves as a base for more specific classes: `SVGElement`, `XMLElement` (we don't need them here) and `HTMLElement`. + +- Finally, [HTMLElement](https://html.spec.whatwg.org/multipage/dom.html#htmlelement) is the basic class for all HTML elements. We'll work with it most of the time. + + It is inherited by concrete HTML elements: + - [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) -- the class for `` elements, + - [HTMLBodyElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlbodyelement) -- the class for `` elements, + - [HTMLAnchorElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement) -- the class for `
` elements, + - ...and so on. + +There are many other tags with their own classes that may have specific properties and methods, while some elements, such as ``, `
`, `
` do not have any specific properties, so they are instances of `HTMLElement` class. + +So, the full set of properties and methods of a given node comes as the result of the chain of inheritance. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, `` element uchun DOM obyektini ko'rib chiqaylik. U [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) klassiga tegishli. @@ -134,14 +174,22 @@ Masalan: ```html run - ``` +<<<<<<< HEAD Ammo istisnolar mavjud, masalan `input.value` faqat atribut -> xususiyatga sinxronlanadi, lekin orqaga emas: +======= +But there are exclusions, for instance `input.value` synchronizes only from attribute -> property, but not back: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```html run diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html index 1bc0d9e45..7fe95e6a9 100644 --- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html +++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html @@ -1,20 +1,74 @@ +<<<<<<< HEAD + + + + +
+ hh:mm:ss +
+ + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19
diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md index 817bbbe9c..66e24c7e3 100644 --- a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md +++ b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md @@ -22,6 +22,10 @@ Nega bunday bo'ladi? alert(table); // stol, xuddi shunday bo'lishi kerak table.remove(); +<<<<<<< HEAD // nega hujjatda hali ham aaa bor? +======= + // why there's still "aaa" in the document? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md index 4bbfef1c0..57afd6ada 100644 --- a/2-ui/1-document/08-styles-and-classes/article.md +++ b/2-ui/1-document/08-styles-and-classes/article.md @@ -128,8 +128,21 @@ setTimeout(() => (document.body.style.display = ""), 1000); // normalga qaytaris Agar `style.display` ni bo'sh satrga o'rnatdik, brauzer CSS sinflarini va o'zining o'rnatilgan uslublarini normal ravishda qo'llaydi, go'yo bunday `style.display` xususiyati umuman yo'qdek. +<<<<<<< HEAD ````smart header="`style.cssText`bilan to'liq qayta yozish" Odatda biz alohida uslub xususiyatlarini belgilash uchun`style.\*`dan foydalanamiz. Biz`div.style="color: red; width: 100px"`kabi to'liq uslubni o'rnatay olmaymiz, chunki`div.style` obyekt va u faqat o'qish uchun. +======= +Also there is a special method for that, `elem.style.removeProperty('style property')`. So, We can remove a property like this: + +```js run +document.body.style.background = 'red'; //set background to red + +setTimeout(() => document.body.style.removeProperty('background'), 1000); // remove background after 1 second +``` + +````smart header="Full rewrite with `style.cssText`" +Normally, we use `style.*` to assign individual style properties. We can't set the full style like `div.style="color: red; width: 100px"`, because `div.style` is an object, and it's read-only. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 To'liq uslubni satr sifatida o'rnatish uchun maxsus `style.cssText` xususiyati mavjud: @@ -261,6 +274,7 @@ Shunday qilib, hozirda `getComputedStyle` aslida xususiyatning hal qilingan qiym ````warn header="`getComputedStyle` to'liq xususiyat nomini talab qiladi" Biz har doim xohlagan aniq xususiyatni so'rashimiz kerak, masalan `paddingLeft` yoki `marginTop` yoki `borderTopWidth`. Aks holda to'g'ri natija kafolatlanmaydi. +<<<<<<< HEAD Masalan, agar `paddingLeft/paddingTop` xususiyatlari bo'lsa, `getComputedStyle(elem).padding` uchun nimani olishimiz kerak? Hech narsa yoki ma'lum paddinglardan "yaratilgan" qiymatmi? Bu yerda standart qoida yo'q. Boshqa nomuvofiqliklar ham bor. Misol tariqasida, ba'zi brauzerlar (Chrome) quyidagi hujjatda `10px` ko'rsatadi, ba'zilari (Firefox) esa ko'rsatmaydi: @@ -277,6 +291,10 @@ Boshqa nomuvofiqliklar ham bor. Misol tariqasida, ba'zi brauzerlar (Chrome) quyi ``` ````` +======= +For instance, if there are properties `paddingLeft/paddingTop`, then what should we get for `getComputedStyle(elem).padding`? Nothing, or maybe a "generated" value from known paddings? There's no standard rule here. +```` +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="`:visited`havolalarga qo'llaniladigan uslublar yashirin!" Tashrif buyurilgan havolalar`:visited` CSS psevdosinfi yordamida ranglanishi mumkin. diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md index f70f134bd..3a59e6bf8 100644 --- a/2-ui/1-document/09-size-and-scroll/article.md +++ b/2-ui/1-document/09-size-and-scroll/article.md @@ -14,7 +14,11 @@ Xususiyatlarni namoyish etish uchun namuna element sifatida quyidagini ishlatami #example { width: 300px; height: 200px; +<<<<<<< HEAD border: 25px solid #e8c48f; +======= + border: 25px solid #E8C48F; +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 padding: 20px; overflow: auto; } @@ -105,7 +109,11 @@ Geometrik xususiyatlar faqat ko'rsatilgan elementlar uchun hisoblanadi. Agar element (yoki uning ajdodlaridan biri) `display:none` ga ega bo'lsa yoki hujjatda bo'lmasa, barcha geometrik xususiyatlar nolga teng (`offsetParent` uchun `null`). +<<<<<<< HEAD Masalan, biz element yaratganimizda, lekin uni hali hujjatga qo'ymaganimizda yoki u (yoki uning ajdodi) `display:none` ga ega bo'lganda `offsetParent` `null` va `offsetWidth`, `offsetHeight` `0` bo'ladi. +======= +For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0` when we created an element, but haven't inserted it into the document yet, or it (or its ancestor) has `display:none`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biz buni element yashirin ekanligini tekshirish uchun ishlatishimiz mumkin: @@ -115,7 +123,11 @@ function isHidden(elem) { } ``` +<<<<<<< HEAD E'tibor bering, bunday `isHidden` ekranda bo'lgan, lekin nol o'lchamga ega elementlar (bo'sh `
` kabi) uchun `true` qaytaradi. +======= +Please note that such `isHidden` returns `true` for elements that are on-screen, but have zero sizes. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```` ## clientTop/Left diff --git a/2-ui/1-document/11-coordinates/article.md b/2-ui/1-document/11-coordinates/article.md index 60b5b9e3d..d07e5f7b8 100644 --- a/2-ui/1-document/11-coordinates/article.md +++ b/2-ui/1-document/11-coordinates/article.md @@ -36,7 +36,11 @@ Qo'shimcha ravishda, hosila xususiyatlar mavjud: ```online Misol uchun, ushbu tugmani bosing va uning oyna koordinatalarini ko'ring: +<<<<<<< HEAD

+======= +

+>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` +<<<<<<< HEAD Ko'rib turganimizdek, `addEventListener` ishlov beruvchi sifatida obyektni qabul qilganda, u hodisa holatida `obj.handleEvent(event)` ni chaqiradi. +======= +As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event. + +We could also use objects of a custom class, like this: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Buning uchun sinfdan ham foydalanishimiz mumkin: @@ -392,6 +429,7 @@ Buning uchun sinfdan ham foydalanishimiz mumkin: *!* let menu = new Menu(); + elem.addEventListener('mousedown', menu); elem.addEventListener('mouseup', menu); */!* diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index 7c64fbf51..c8e7fb180 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -119,27 +119,46 @@ Bubbling ni oldini olishning haqiqiy zarurati odatda yo'q. Bu talab qilinadigan "Capturing" deb ataladigan hodisa qayta ishlashning yana bir fazasi mavjud. U haqiqiy kodda kamdan-kam qo'llaniladi, lekin ba'zan foydali bo'lishi mumkin. +<<<<<<< HEAD Standart [DOM Events](http://www.w3.org/TR/DOM-Level-3-Events/) hodisa tarqalishining 3 fazasini tasvirlaydi: +======= +The standard [DOM Events](https://www.w3.org/TR/DOM-Level-3-Events/) describes 3 phases of event propagation: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 1. Capturing fazasi -- hodisa elementga pastga boradi. 2. Target fazasi -- hodisa target elementga yetdi. 3. Bubbling fazasi -- hodisa elementdan yuqoriga bubble qiladi. +<<<<<<< HEAD Mana jadval ichidagi `` ga bosishning spetsifikatsiyadan olingan rasmi: +======= +Here's the picture, taken from the specification, of the capturing `(1)`, target `(2)` and bubbling `(3)` phases for a click event on a `` inside a table: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ![](eventflow.svg) Ya'ni: `` ga bosish uchun hodisa avval ajdodlar zanjiri orqali elementga pastga boradi (capturing fazasi), keyin target ga yetadi va u yerda ishga tushadi (target fazasi), so'ngra yuqoriga boradi (bubbling fazasi), yo'lda ishlov beruvchilarni chaqiradi. +<<<<<<< HEAD **Ilgari biz faqat bubbling haqida gapirdik, chunki capturing fazasi kamdan-kam ishlatiladi. Odatda u bizga ko'rinmaydi.** `on`-xossasi yoki HTML atributlari yordamida yoki ikki argumentli `addEventListener(event, handler)` dan foydalanib qo'shilgan ishlov beruvchilar capturing haqida hech narsa bilmaydi, ular faqat 2-chi va 3-chi fazalarda ishlaydi. +======= +Until now, we only talked about bubbling, because the capturing phase is rarely used. + +In fact, the capturing phase was invisible for us, because handlers added using `on`-property or using HTML attributes or using two-argument `addEventListener(event, handler)` don't know anything about capturing, they only run on the 2nd and 3rd phases. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Capturing fazasida hodisani ushlash uchun ishlov beruvchining `capture` parametrini `true` qilib o'rnatishimiz kerak: ```js elem.addEventListener(..., {capture: true}) +<<<<<<< HEAD // yoki, shunchaki "true" {capture: true} ning taxallusi +======= + +// or, just "true" is an alias to {capture: true} +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 elem.addEventListener(..., true) ``` @@ -178,9 +197,16 @@ Kod hujjatdagi *har* elementga bosish ishlov beruvchisini o'rnatadi, qaysi biri Agar siz `

` ga bossangiz, ketma-ketlik quyidagicha bo'ladi: +<<<<<<< HEAD 1. `HTML` -> `BODY` -> `FORM` -> `DIV` (capturing fazasi, birinchi tinglovchi): 2. `P` (target fazasi, ikki marta ishga tushadi, chunki biz ikkita tinglovchi o'rnatdik: capturing va bubbling) 3. `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling fazasi, ikkinchi tinglovchi). +======= +1. `HTML` -> `BODY` -> `FORM` -> `DIV -> P` (capturing phase, the first listener): +2. `P` -> `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling phase, the second listener). + +Please note, the `P` shows up twice, because we've set two listeners: capturing and bubbling. The target triggers at the end of the first and at the beginning of the second phase. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `event.eventPhase` xossasi mavjud bo'lib, u hodisa qaysi fazada ushlanganligining raqamini aytadi. Lekin u kamdan-kam ishlatiladi, chunki biz odatda buni ishlov beruvchida bilamiz. @@ -188,8 +214,13 @@ Agar siz `

` ga bossangiz, ketma-ketlik quyidagicha bo'ladi: Agar biz `addEventListener(..., true)` qilsak, ishlov beruvchini to'g'ri olib tashlash uchun `removeEventListener(..., true)` da bir xil fazani eslatishimiz kerak. ``` +<<<<<<< HEAD ````smart header="Bir elementda va bir fazada tinglovchilar o'rnatilgan tartibda ishlaydi" Agar bizda `addEventListener` bilan bir xil elementga tayinlangan bir xil fazada bir nechta hodisa ishlov beruvchi bo'lsa, ular yaratilgan tartibda ishlaydi: +======= +````smart header="Listeners on the same element and same phase run in their set order" +If we have multiple event handlers on the same phase, assigned to the same element with `addEventListener`, they run in the same order as they are created: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js elem.addEventListener("click", e => alert(1)); // birinchi bo'lib ishga tushishi kafolatlanagan @@ -197,7 +228,16 @@ elem.addEventListener("click", e => alert(2)); ``` ```` +<<<<<<< HEAD ## Xulosa +======= +```smart header="The `event.stopPropagation()` during the capturing also prevents the bubbling" +The `event.stopPropagation()` method and its sibling `event.stopImmediatePropagation()` can also be called on the capturing phase. Then not only the futher capturing is stopped, but the bubbling as well. + +In other words, normally the event goes first down ("capturing") and then up ("bubbling"). But if `event.stopPropagation()` is called during the capturing phase, then the event travel stops, no bubbling will occur. +``` + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Hodisa sodir bo'lganda -- u sodir bo'lgan eng ichki element "target element" (`event.target`) sifatida belgilanadi. @@ -215,7 +255,11 @@ Har qanday hodisa ishlov beruvchi `event.stopPropagation()` ni chaqirib hodisani Capturing fazasi juda kamdan-kam ishlatiladi, odatda biz hodisalarni bubbling da qayta ishlaymiz. Va buning ortida mantiq bor. +<<<<<<< HEAD Haqiqiy dunyoda baxtsiz hodisa sodir bo'lganda, mahalliy hokimiyat avval javob beradi. Ular hodisa sodir bo'lgan hududni eng yaxshi biladi. Keyin kerak bo'lsa yuqori darajadagi hokimiyat. +======= +The capturing phase is used very rarely, usually we handle events on bubbling. And there's a logical explanation for that. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Hodisa ishlov beruvchilari uchun ham xuddi shunday. Ma'lum bir elementga ishlov beruvchi o'rnatgan kod element va uning nima qilishi haqida maksimal tafsilotlarni biladi. Ma'lum bir `` dagi ishlov beruvchi aynan o'sha `` uchun mos kelishi mumkin, u haqida hamma narsani biladi, shuning uchun birinchi imkoniyatni olishi kerak. Keyin uning bevosita ota-onasi ham kontekst haqida biladi, lekin biroz kamroq, va hokazo umumiy tushunchalarni qayta ishlovchi va oxirgi ishlaydigan eng yuqori elementgacha. diff --git a/2-ui/2-events/03-event-delegation/article.md b/2-ui/2-events/03-event-delegation/article.md index b547f1fb7..bd0881f71 100644 --- a/2-ui/2-events/03-event-delegation/article.md +++ b/2-ui/2-events/03-event-delegation/article.md @@ -2,7 +2,11 @@ Ushlash va bubbling bizga *hodisa delegatsiyasi* deb ataladigan eng kuchli hodisa qayta ishlash shakllaridan birini amalga oshirishga imkon beradi. +<<<<<<< HEAD G'oya shundaki, agar bizda o'xshash tarzda qayta ishlanadigan ko'plab elementlar bo'lsa, ularning har biriga ishlov beruvchi tayinlash o'rniga -- ularning umumiy ajdodiga bitta ishlov beruvchi qo'yamiz. +======= +Capturing and bubbling allow us to implement one of the most powerful event handling patterns called *event delegation*. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ishlov beruvchida biz `event.target` dan hodisa qayerda sodir bo'lganini bilish va uni qayta ishlash uchun foydalanamiz. diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css index 746f8c93b..47e4eb361 100644 --- a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css +++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css @@ -4,6 +4,7 @@ body { font: 75%/120% sans-serif; } +<<<<<<< HEAD h2 { font: bold 190%/100% sans-serif; margin: 0 0 0.2em; @@ -14,6 +15,8 @@ h2 em { color: #999999; } +======= +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 #largeImg { border: solid 1px #ccc; width: 550px; diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css b/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css index 1bdf5248f..585073c28 100644 --- a/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css +++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css @@ -4,6 +4,7 @@ body { font: 75%/120% sans-serif; } +<<<<<<< HEAD h2 { font: bold 190%/100% sans-serif; margin: 0 0 0.2em; @@ -14,6 +15,8 @@ h2 em { color: #999999; } +======= +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 #largeImg { border: solid 1px #ccc; width: 550px; @@ -31,5 +34,19 @@ h2 em { } #thumbs a:hover { +<<<<<<< HEAD border-color: #ff9900; } +======= + border-color: #FF9900; +} + +#thumbs li { + list-style: none; +} + +#thumbs { + margin: 0; + padding: 0; +} +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md index 5bda1a531..433eb926f 100644 --- a/2-ui/2-events/04-default-browser-action/article.md +++ b/2-ui/2-events/04-default-browser-action/article.md @@ -17,7 +17,11 @@ Brauzerni harakat qilishini istamasligimizni aytishning ikki yo'li bor: - Asosiy usul `event` obyektidan foydalanishdir. `event.preventDefault()` metodi mavjud. - Agar ishlov beruvchi `on` yordamida tayinlangan bo'lsa (`addEventListener` orqali emas), u holda `false` qaytarish ham bir xil ishlaydi. +<<<<<<< HEAD Bu HTML kodida havolaga bosish yo'naltirish olib kelmaydi, brauzer hech narsa qilmaydi: +======= +In this HTML, a click on a link doesn't lead to navigation; the browser doesn't do anything: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```html autorun height=60 no-beautify Bu yerga bosing @@ -96,7 +100,11 @@ Buning sababi `mousedown` da brauzer harakati bekor qilingandir. Boshqa yo'l bil `addEventListener` ning ixtiyoriy `passive: true` parametri brauzerni ishlov beruvchi `preventDefault()` ni chaqirmasligini bildiradi. +<<<<<<< HEAD Bu nima uchun kerak bo'lishi mumkin? +======= +Why might that be needed? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Mobil qurilmalarda `touchmove` kabi ba'zi hodisalar mavjud (foydalanuvchi barmog'ini ekran bo'ylab siljitganda), ular sukut bo'yicha scroll qilishga sabab bo'ladi, lekin bu scroll `preventDefault()` yordamida ishlov beruvchida oldini olish mumkin. diff --git a/2-ui/2-events/05-dispatch-events/article.md b/2-ui/2-events/05-dispatch-events/article.md index 659cec932..68ab27454 100644 --- a/2-ui/2-events/05-dispatch-events/article.md +++ b/2-ui/2-events/05-dispatch-events/article.md @@ -8,7 +8,11 @@ Biz nafaqat o'z maqsadlarimiz uchun ixtiro qilgan butunlay yangi eventlarni, bal ## Event konstruktor +<<<<<<< HEAD O'rnatilgan event sinflari DOM element sinflariga o'xshash ierarxiya hosil qiladi. Ildizi o'rnatilgan [Event](http://www.w3.org/TR/dom/#event) sinfi. +======= +Built-in event classes form a hierarchy, similar to DOM element classes. The root is the built-in [Event](https://dom.spec.whatwg.org/#events) class. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biz `Event` obyektlarini quyidagicha yaratishimiz mumkin: @@ -209,7 +213,11 @@ E'tibor bering: eventda `cancelable: true` bayrog'i bo'lishi kerak, aks holda `e ## Eventlar ichida eventlar sinxrondir +<<<<<<< HEAD Odatda eventlar navbatda qayta ishlanadi. Ya'ni: brauzer `onclick` ni qayta ishlayotgan bo'lsa va yangi event sodir bo'lsa, masalan sichqon harakatlandi, uning qayta ishlanishi navbatga qo'yiladi, tegishli `mousemove` handlerlari `onclick` qayta ishlanishi tugagandan keyin chaqiriladi. +======= +Usually events are processed in a queue. That is: if the browser is processing `onclick` and a new event occurs, e.g. mouse moved, then its handling is queued up, corresponding `mousemove` handlers will be called after `onclick` processing is finished. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Muhim istisno - bitta event boshqasining ichidan ishga tushirilganda, masalan `dispatchEvent` yordamida. Bunday eventlar darhol qayta ishlanadi: yangi event handlerlari chaqiriladi, keyin joriy event qayta ishlanishi davom etadi. diff --git a/2-ui/3-event-details/1-mouse-events-basics/article.md b/2-ui/3-event-details/1-mouse-events-basics/article.md index 6e97b66c7..0f020c24a 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/article.md +++ b/2-ui/3-event-details/1-mouse-events-basics/article.md @@ -1,4 +1,9 @@ +<<<<<<< HEAD # Sichqoncha hodisalari +======= + +# Mouse events +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ushbu bobda sichqoncha hodisalari va ularning xossalari haqida batafsil ma'lumot beramiz. @@ -39,9 +44,15 @@ Bitta harakat bir nechta hodisalarni boshlagan hollarda, ularning tartibi belgil ```online Quyidagi tugmani bosing va hodisalarni ko'rasiz. Ikki marta bosishni ham sinab ko'ring. +<<<<<<< HEAD Quyidagi test stendida barcha sichqoncha hodisalari qayd qilinadi va agar ular orasida 1 soniyadan ko'proq kechikish bo'lsa, ular gorizontal chiziq bilan ajratiladi. Shuningdek, sichqoncha tugmasini aniqlashga imkon beruvchi `button` xossasini ko'rishimiz mumkin, u quyida tushuntiriladi. +======= +On the teststand below, all mouse events are logged, and if there is more than a 1 second delay between them, they are separated by a horizontal rule. + +Also, we can see the `button` property that allows us to detect the mouse button; it's explained below. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19

``` @@ -52,7 +63,11 @@ Bosishga bog'liq hodisalar doim aynan qaysi sichqoncha tugmasini olish imkonini Biz odatda uni `click` va `contextmenu` hodisalari uchun ishlatmaymiz, chunki birinchisi faqat chap bosishda, ikkinchisi esa faqat o'ng bosishda sodir bo'ladi. +<<<<<<< HEAD Boshqa tomondan, `mousedown` va `mouseup` ishlov beruvchilari `event.button` ga muhtoj bo'lishi mumkin, chunki bu hodisalar har qanday tugmada ishga tushadi, shuning uchun `button` "o'ng-mousedown" va "chap-mousedown" o'rtasida farq qilish imkonini beradi. +======= +On the other hand, `mousedown` and `mouseup` handlers may need `event.button`, because these events trigger on any button, so `button` allows to distinguish between "right-mousedown" and "left-mousedown". +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `event.button` ning mumkin bo'lgan qiymatlari: @@ -154,7 +169,11 @@ Va agar sichqoncha markazda bo'lsa, hujjatda qaysi joyda bo'lishidan qat'i nazar ## mousedown da tanlovni oldini olish +<<<<<<< HEAD Ikki marta sichqoncha bosish ba'zi interfeyslarda bezovta qiluvchi yon ta'sirga ega: u matnni tanlaydi. +======= +Double mouse click has a side effect that may be disturbing in some interfaces: it selects text. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Masalan, quyidagi matnni ikki marta bosish bizning ishlov beruvchimizdan tashqari uni tanlaydi: diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html index 9d66c38f1..77379dcb1 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html @@ -1,11 +1,102 @@ +<<<<<<< HEAD + + + + + +
+
+ +

Once upon a time there was a mother pig who had three little pigs.

+ +

The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."

+ +

The three little pigs set off. "We will take care that the wolf does not catch us," they said.

+ +

Soon they met a man. Hover over me

+ +
+ + +======= +

The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."

+ +

The three little pigs set off. "We will take care that the wolf does not catch us," they said.

+ +

Soon they met a man. Hover over me

+ +
+ + + + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js index 9a531644e..106d360df 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js @@ -86,7 +86,7 @@ class HoverIntent { if (speed < this.sensitivity) { clearInterval(this.checkSpeedInterval); this.isHover = true; - this.over.call(this.elem, event); + this.over.call(this.elem); } else { // tez suring, oldingi kabi yangi koordinatalarni eslab qoling this.prevX = this.lastX; diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js index b3898f9fa..daa29ca19 100755 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js @@ -3,7 +3,11 @@ parent.onmouseover = parent.onmouseout = parent.onmousemove = handler; function handler(event) { let type = event.type; +<<<<<<< HEAD while (type < 11) type += " "; +======= + while (type.length < 11) type += ' '; +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 log(type + " target=" + event.target.id); return false; diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md index 287789b9b..807c509a2 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md @@ -18,11 +18,16 @@ Asosiy Drag'n'Drop algoritmi quyidagicha ko'rinadi: 2. Keyin `mousemove` da uni `position:absolute` bilan `left/top` ni o'zgartirib harakat qildiring. 3. `mouseup` da - drag'n'drop ni tugatish bilan bog'liq barcha harakatlarni bajaring. +<<<<<<< HEAD Bular asoslar. Keyinroq boshqa xususiyatlarni, masalan ular ustidan sudrab o'tayotganda joriy pastki elementlarni ajratib ko'rsatishni qanday qo'shishni ko'ramiz. +======= +These are the basics. Later we'll see how to add other features, such as highlighting current underlying elements while we drag over them. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 To'pni sudrab olib ketish amalga oshirilishi: ```js +<<<<<<< HEAD ball.onmousedown = function(event) { // (1) harakatga tayyorlash: absolyut qiling va z-index orqali yuqoriga ball.style.position = 'absolute'; @@ -31,6 +36,16 @@ ball.onmousedown = function(event) { // uni har qanday joriy ota-onalardan to'g'ridan-to'g'ri body ga ko'chiring // uni body ga nisbatan joylashtirilgan qilish uchun document.body.append(ball); +======= +ball.onmousedown = function(event) { + // (1) prepare to moving: make absolute and on top by z-index + ball.style.position = 'absolute'; + ball.style.zIndex = 1000; + + // move it out of any current parents directly into body + // to make it positioned relative to the body + document.body.append(ball); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 // to'pni (pageX, pageY) koordinatalarida markazlashtiradi function moveAt(pageX, pageY) { @@ -93,14 +108,22 @@ Shuning uchun biz uni ushlash uchun `document` ga tinglashimiz kerak. ## To'g'ri joylashtiruv +<<<<<<< HEAD Yuqoridagi misollarda to'p doim shunday harakat qiltirilganki, uning markazi ko'rsatkich ostida bo'ladi: +======= +In the examples above the ball is always moved so that its center is under the pointer: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```js ball.style.left = pageX - ball.offsetWidth / 2 + 'px'; ball.style.top = pageY - ball.offsetHeight / 2 + 'px'; ``` +<<<<<<< HEAD Yomon emas, lekin yon ta'sir bor. Drag'n'drop ni boshlash uchun biz to'pni istalgan joyiga `mousedown` qilishimiz mumkin. Lekin agar uni chekkasidan "olsak", to'p to'satdan sichqoncha ko'rsatkichi ostida markazlashish uchun "sakraydi". +======= +Not bad, but there's a side effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if "take" it from its edge, then the ball suddenly "jumps" to become centered under the mouse pointer. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Agar biz elementning ko'rsatkichga nisbatan boshlang'ich siljishini saqlasak yaxshiroq bo'lardi. @@ -219,7 +242,11 @@ Shuning uchun potentsial tashlanadigan narsalarga ishlov beruvchilar qo'yish bos Xo'sh, nima qilish kerak? +<<<<<<< HEAD `document.elementFromPoint(clientX, clientY)` deb ataladigan usul bor. U berilgan oynaga nisbatan koordinatalardagi eng ichki elementni qaytaradi (yoki koordinatalar oynadan tashqarida bo'lsa `null`). +======= +There's a method called `document.elementFromPoint(clientX, clientY)`. It returns the most nested element on given window-relative coordinates (or `null` if given coordinates are out of the window). If there are multiple overlapping elements on the same coordinates, then the topmost one is returned. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biz uni istalgan sichqoncha hodisa ishlov beruvchida ko'rsatkich ostidagi potentsial tashlanadigan narsani aniqlash uchun ishlatishimiz mumkin: diff --git a/2-ui/3-event-details/6-pointer-events/article.md b/2-ui/3-event-details/6-pointer-events/article.md index ddda7cd00..98d9b29d0 100644 --- a/2-ui/3-event-details/6-pointer-events/article.md +++ b/2-ui/3-event-details/6-pointer-events/article.md @@ -8,17 +8,31 @@ Kichik sharh beramiz, shunda siz umumiy rasmni va Pointer hodisalarning boshqa h - Uzoq vaqt oldin, o'tmishda faqat sichqoncha hodisalari mavjud edi. +<<<<<<< HEAD Keyin sensorli qurilmalar, xususan telefonlar va planshetlar keng tarqaldi. Mavjud skriptlar ishlashi uchun ular sichqoncha hodisalarini hosil qildi (va hali ham qiladilar). Masalan, sensorli ekranga tegish `mousedown` ni hosil qiladi. Shuning uchun sensorli qurilmalar veb-sahifalar bilan yaxshi ishladi. Lekin sensorli qurilmalar sichqonchadan ko'proq imkoniyatlarga ega. Masalan, bir vaqtda bir nechta nuqtaga tegish mumkin ("multi-touch"). Garchi, sichqoncha hodisalarida bunday multi-touchlarni qayta ishlash uchun kerakli xossalar yo'q. +======= + Then touch devices became widespread, phones and tablets in particular. For the existing scripts to work, they generated (and still generate) mouse events. For instance, tapping a touchscreen generates `mousedown`. So touch devices worked well with web pages. + + But touch devices have more capabilities than a mouse. For example, it's possible to touch multiple points at once ("multi-touch"). Although, mouse events don't have necessary properties to handle such multi-touches. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - Shuning uchun `touchstart`, `touchend`, `touchmove` kabi touch hodisalari kiritildi, ularda touchga xos xossalar bor (biz ularni batafsil ko'rib chiqmaymiz, chunki pointer hodisalari yanada yaxshiroq). +<<<<<<< HEAD Shunga qaramay, bu yetarli emas edi, chunki qalam kabi o'ziga xos xususiyatlarga ega ko'plab boshqa qurilmalar mavjud. Bundan tashqari, ham touch, ham sichqoncha hodisalarini tinglovchi kod yozish mashaqqatli edi. +======= + Still, it wasn't enough, as there are many other devices, such as pens, that have their own features. Also, writing code that listens for both touch and mouse events was cumbersome. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - Bu muammolarni hal qilish uchun yangi standart Pointer hodisalari kiritildi. U barcha turdagi ko'rsatkich qurilmalari uchun yagona hodisalar to'plamini taqdim etadi. +<<<<<<< HEAD Hozirda [Pointer Events Level 2](https://www.w3.org/TR/pointerevents2/) spetsifikatsiyasi barcha asosiy brauzerlarda qo'llab-quvvatlanadi, yangi [Pointer Events Level 3](https://w3c.github.io/pointerevents/) esa ishlab chiqilmoqda va asosan Pointer Events level 2 bilan mos keladi. +======= +As of now, [Pointer Events Level 2](https://www.w3.org/TR/pointerevents2/) specification is supported in all major browsers, while the newer [Pointer Events Level 3](https://w3c.github.io/pointerevents/) is in the works and is mostly compatible with Pointer Events level 2. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Agar siz Internet Explorer 10 yoki Safari 12 va undan pastroq kabi eski brauzerlar uchun ishlab chiqmasangiz, endi sichqoncha yoki touch hodisalaridan foydalanishning ma'nosi yo'q -- biz pointer hodisalariga o'tishimiz mumkin. @@ -43,33 +57,56 @@ Pointer hodisalari sichqoncha hodisalariga o'xshash nomlanadi: | `gotpointercapture` | - | | `lostpointercapture` | - | +<<<<<<< HEAD Ko'rib turganimizdek, har bir `mouse` uchun o'xshash rol o'ynaydigan `pointer` mavjud. Bundan tashqari, mos keladigan `mouse...` qariydoshi bo'lmagan 3 ta qo'shimcha pointer hodisasi mavjud, biz ularni tez orada tushuntiramiz. +======= +As we can see, for every `mouse`, there's a `pointer` that plays a similar role. Also there are 3 additional pointer events that don't have a corresponding `mouse...` counterpart, we'll explain them soon. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```smart header="Kodimizdagi `mouse` ni `pointer` bilan almashtirish" Biz kodimizdagi `mouse` hodisalarini `pointer` bilan almashtirshimiz va sichqoncha bilan ishlashda davom etishini kutishimiz mumkin. +<<<<<<< HEAD Sensorli qurilmalar uchun qo'llab-quvvatlash ham "sehrli" tarzda yaxshilanadi. Garchi, CSS da ba'zi joylarda `touch-action: none` qo'shishimiz kerak bo'lishi mumkin. Buni quyida `pointercancel` haqidagi bo'limda ko'rib chiqamiz. +======= +The support for touch devices will also "magically" improve. Although, we may need to add `touch-action: none` in some places in CSS. We'll cover it below in the section about `pointercancel`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ## Pointer hodisa xossalari Pointer hodisalari sichqoncha hodisalari bilan bir xil xossalarga ega, masalan `clientX/Y`, `target` va h.k., shuningdek ba'zi boshqalar: +<<<<<<< HEAD - `pointerId` - hodisani keltirib chiqaruvchi pointerning noyob identifikatori. Brauzer tomonidan yaratiladi. Ko'p pointerlarni qayta ishlashga imkon beradi, masalan stylusli sensorli ekran va multi-touch (misollar keyinroq keladi). - `pointerType` - ko'rsatkich qurilmasi turi. Satr bo'lishi kerak, quyidagilardan biri: "mouse", "pen" yoki "touch". +======= +- `pointerId` - the unique identifier of the pointer causing the event. + + Browser-generated. Allows us to handle multiple pointers, such as a touchscreen with stylus and multi-touch (examples will follow). +- `pointerType` - the pointing device type. Must be a string, one of: "mouse", "pen" or "touch". +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biz bu xossani turli pointer turlariga turlicha javob berish uchun ishlatishimiz mumkin. - `isPrimary` - asosiy pointer uchun `true` (multi-touchda birinchi barmoq). Ba'zi pointer qurilmalari kontakt maydoni va bosimni o'lchaydi, masalan sensorli ekrandagi barmoq uchun buning uchun qo'shimcha xossalar mavjud: +<<<<<<< HEAD - `width` - pointer (masalan barmoq) qurilmaga teginadigan maydonning kengligi. Qo'llab-quvvatlanmagan joylarda, masalan sichqoncha uchun, u doim `1`. - `height` - pointer qurilmaga teginadigan maydonning balandligi. Qo'llab-quvvatlanmagan joylarda, u doim `1`. - `pressure` - pointer uchining bosimi, 0 dan 1 gacha diapazonda. Bosimni qo'llab-quvvatlamaydigan qurilmalar uchun `0.5` (bosilgan) yoki `0` bo'lishi kerak. - `tangentialPressure` - normallashtirilgan tangensial bosim. - `tiltX`, `tiltY`, `twist` - qalamga xos xossalar, qalam sirtga nisbatan qanday joylashganini tasvirlaydi. +======= +- `width` - the width of the area where the pointer (e.g. a finger) touches the device. Where unsupported, e.g. for a mouse, it's always `1`. +- `height` - the height of the area where the pointer touches the device. Where unsupported, it's always `1`. +- `pressure` - the pressure of the pointer tip, in range from 0 to 1. For devices that don't support pressure must be either `0.5` (pressed) or `0`. +- `tangentialPressure` - the normalized tangential pressure. +- `tiltX`, `tiltY`, `twist` - pen-specific properties that describe how the pen is positioned relative to the surface. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Bu xossalar ko'pchilik qurilmalarda qo'llab-quvvatlanmaydi, shuning uchun kamdan-kam ishlatiladi. Kerak bo'lsa, ular haqida batafsil ma'lumotni [spetsifikatsiya](https://w3c.github.io/pointerevents/#pointerevent-interface)da topishingiz mumkin. @@ -102,16 +139,29 @@ Diqqat qiling: `pointerId/isPrimary` dagi farqni haqiqatdan ham ko'rish uchun te ## Hodisa: pointercancel +<<<<<<< HEAD `pointercancel` hodisasi davom etayotgan pointer o'zaro ta'sir bo'lganda ishga tushadi va keyin uni bekor qiladigan narsa sodir bo'ladi, shuning uchun boshqa pointer hodisalar hosil bo'lmaydi. Bunday sabablar: - Pointer qurilmasi apparati jismonan o'chirilgan. - Qurilma orientatsiyasi o'zgargan (planshet aylantirilgan). - Brauzer o'zaro ta'sirni o'zi boshqarishga qaror qilgan, uni sichqoncha harakati yoki zoom va pan harakati yoki boshqa narsa deb hisoblagan. +======= +The `pointercancel` event fires when there's an ongoing pointer interaction, and then something happens that causes it to be aborted, so that no more pointer events are generated. + +Such causes are: +- The pointer device hardware was physically disabled. +- The device orientation changed (tablet rotated). +- The browser decided to handle the interaction on its own, considering it a mouse gesture or zoom-and-pan action or something else. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 `pointercancel` ni bizga qanday ta'sir qilishini ko'rish uchun amaliy misolda namoyish etamiz. +<<<<<<< HEAD Aytaylik, biz maqolasining boshidagi kabi to'p uchun drag'n'drop ni amalga oshirmoqdamiz. +======= +Let's say we're implementing drag'n'drop for a ball, just as in the beginning of the article . +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Mana foydalanuvchi harakatlari oqimi va tegishli hodisalar: @@ -126,7 +176,11 @@ Mana foydalanuvchi harakatlari oqimi va tegishli hodisalar: Demak, muammo shundaki, brauzer o'zaro ta'sirni "o'g'irlaydi": "drag-and-drop" jarayonining boshida `pointercancel` ishga tushadi va boshqa `pointermove` hodisalari hosil bo'lmaydi. ```online +<<<<<<< HEAD Mana pointer hodisalarini qayd qiluvchi drag'n'drop demosi (`textarea` da faqat `up/down`, `move` va `cancel`): +======= +Here's the drag'n'drop demo with logging of pointer events (only `up/down`, `move` and `cancel`) in the `textarea`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 [iframe src="ball" height=240 edit] ``` @@ -137,12 +191,21 @@ Biz drag'n'drop ni o'zimiz amalga oshirmoqchimiz, shuning uchun brauzerni buni o Bizga ikki narsa qilish kerak: +<<<<<<< HEAD 1. Mahalliy drag'n'drop sodir bo'lishining oldini olish: - Buni maqolasida tasvirlanganidek `ball.ondragstart = () => false` o'rnatish orqali qilishimiz mumkin. - Bu sichqoncha hodisalari uchun yaxshi ishlaydi. 2. Sensorli qurilmalar uchun boshqa touch bilan bog'liq brauzer harakatlari (drag'n'drop dan tashqari) mavjud. Ular bilan ham muammolardan qochish uchun: - CSS da `#ball { touch-action: none }` o'rnatish orqali ularning oldini oling. - Keyin kodimiz sensorli qurilmalarda ishlay boshlaydi. +======= +1. Prevent native drag'n'drop from happening: + - We can do this by setting `ball.ondragstart = () => false`, just as described in the article . + - That works well for mouse events. +2. For touch devices, there are other touch-related browser actions (besides drag'n'drop). To avoid problems with them too: + - Prevent them by setting `#ball { touch-action: none }` in CSS. + - Then our code will start working on touch devices. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Buni qilganimizdan so'ng, hodisalar mo'ljallanganidek ishlaydi, brauzer jarayonni o'g'irlamaydi va `pointercancel` chiqarmaydi. @@ -162,8 +225,13 @@ Pointer capturing - pointer hodisalarining maxsus xususiyatidir. G'oya juda oddiy, lekin avvaliga juda g'alati tuyulishi mumkin, chunki boshqa hodisa turlari uchun bunday narsa mavjud emas. +<<<<<<< HEAD Asosiy usul: - `elem.setPointerCapture(pointerId)` - berilgan `pointerId` bilan hodisalarni `elem` ga bog'laydi. Chaqiruvdan keyin bir xil `pointerId` ga ega barcha pointer hodisalar `elem` ni target sifatida oladilar (xuddi `elem` da sodir bo'lgandek), hujjatda qayerda sodir bo'lishidan qat'i nazar. +======= +The main method is: +- `elem.setPointerCapture(pointerId)` -- binds events with the given `pointerId` to `elem`. After the call all pointer events with the same `pointerId` will have `elem` as the target (as if happened on `elem`), no matter where in document they really happened. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Boshqacha qilib aytganda, `elem.setPointerCapture(pointerId)` berilgan `pointerId` bilan barcha keyingi hodisalarni `elem` ga qayta yo'naltiradi. @@ -172,6 +240,7 @@ Bog'lanish olib tashlanadi: - `elem` hujjatdan olib tashlanganida avtomatik, - `elem.releasePointerCapture(pointerId)` chaqirilganda. +<<<<<<< HEAD **Pointer capturing drag'n'drop kabi o'zaro ta'sirlarni soddalashtirish uchun ishlatilishi mumkin.** Misol sifatida da tasvirlangan maxsus slayderní qanday amalga oshirishni eslaymiz. @@ -195,6 +264,45 @@ Pointer capturing `pointermove` ni `thumb` ga bog'lash va bunday muammolardan qo - `pointerup` sodir bo'lganda (sudrab tugatilganda), bog'lanish avtomatik olib tashlanadi, bu haqida g'amxo'rlik qilishimiz shart emas. Shunday qilib, foydalanuvchi pointerni butun hujjat bo'ylab harakatlantirsa ham, hodisa ishlov beruvchilar `thumb` da chaqiriladi. Bundan tashqari, hodisa obyektlarining koordinata xossalari, masalan `clientX/clientY` hali ham to'g'ri bo'ladi - capturing faqat `target/currentTarget` ga ta'sir qiladi. +======= +Now what is it good for? It's time to see a real-life example. + +**Pointer capturing can be used to simplify drag'n'drop kind of interactions.** + +Let's recall how one can implement a custom slider, described in the . + +We can make a `slider` element to represent the strip and the "runner" (`thumb`) inside it: + +```html +
+
+
+``` + +With styles, it looks like this: + +[iframe src="slider-html" height=40 edit] + +

+ +And here's the working logic, as it was described, after replacing mouse events with similar pointer events: + +1. The user presses on the slider `thumb` -- `pointerdown` triggers. +2. Then they move the pointer -- `pointermove` triggers, and our code moves the `thumb` element along. + - ...As the pointer moves, it may leave the slider `thumb` element, go above or below it. The `thumb` should move strictly horizontally, remaining aligned with the pointer. + +In the mouse event based solution, to track all pointer movements, including when it goes above/below the `thumb`, we had to assign `mousemove` event handler on the whole `document`. + +That's not a cleanest solution, though. One of the problems is that when a user moves the pointer around the document, it may trigger event handlers (such as `mouseover`) on some other elements, invoke totally unrelated UI functionality, and we don't want that. + +This is the place where `setPointerCapture` comes into play. + +- We can call `thumb.setPointerCapture(event.pointerId)` in `pointerdown` handler, +- Then future pointer events until `pointerup/cancel` will be retargeted to `thumb`. +- When `pointerup` happens (dragging complete), the binding is removed automatically, we don't need to care about it. + +So, even if the user moves the pointer around the whole document, events handlers will be called on `thumb`. Nevertheless, coordinate properties of the event objects, such as `clientX/clientY` will still be correct - the capturing only affects `target/currentTarget`. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Mana asosiy kod: @@ -202,8 +310,23 @@ Mana asosiy kod: thumb.onpointerdown = function(event) { // barcha pointer hodisalarni (pointerup gacha) thumb ga qayta yo'naltirish thumb.setPointerCapture(event.pointerId); + + // start tracking pointer moves + thumb.onpointermove = function(event) { + // moving the slider: listen on the thumb, as all pointer events are retargeted to it + let newLeft = event.clientX - slider.getBoundingClientRect().left; + thumb.style.left = newLeft + 'px'; + }; + + // on pointer up finish tracking pointer moves + thumb.onpointerup = function(event) { + thumb.onpointermove = null; + thumb.onpointerup = null; + // ...also process the "drag end" if needed + }; }; +<<<<<<< HEAD thumb.onpointermove = function(event) { // slayderni harakatlantirish: thumb ni tinglaymiz, chunki barcha pointer hodisalar unga qayta yo'naltiriladi let newLeft = event.clientX - slider.getBoundingClientRect().left; @@ -212,21 +335,47 @@ thumb.onpointermove = function(event) { // diqqat: thumb.releasePointerCapture ni chaqirish shart emas, // u pointerup da avtomatik sodir bo'ladi +======= +// note: no need to call thumb.releasePointerCapture, +// it happens on pointerup automatically +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` ```online To'liq demo: [iframe src="slider" height=100 edit] + +

+ +In the demo, there's also an additional element with `onmouseover` handler showing the current date. + +Please note: while you're dragging the thumb, you may hover over this element, and its handler *does not* trigger. + +So the dragging is now free of side effects, thanks to `setPointerCapture`. ``` +<<<<<<< HEAD Oxir-oqibat, pointer capturing bizga ikkita foyda beradi: 1. Kod tozaroq bo'ladi, chunki biz endi butun `document` da ishlov beruvchilarni qo'shish/olib tashlashimiz shart emas. Bog'lanish avtomatik ravishda chiqariladi. 2. Agar hujjatda biror `pointermove` ishlov beruvchilar bo'lsa, foydalanuvchi slayderni sudrab ketayotganda pointer tomonidan ular tasodifan ishga tushmaydi. +======= + + +At the end, pointer capturing gives us two benefits: +1. The code becomes cleaner as we don't need to add/remove handlers on the whole `document` any more. The binding is released automatically. +2. If there are other pointer event handlers in the document, they won't be accidentally triggered by the pointer while the user is dragging the slider. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ### Pointer capturing hodisalari +<<<<<<< HEAD Ikkita bog'liq pointer hodisasi mavjud: +======= +There's one more thing to mention here, for the sake of completeness. + +There are two events associated with pointer capturing: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 - `gotpointercapture` - element capturing ni yoqish uchun `setPointerCapture` dan foydalanganda ishga tushadi. - `lostpointercapture` - capturing chiqarilganda ishga tushadi: `releasePointerCapture` chaqiruvi bilan aniq yoki `pointerup`/`pointercancel` da avtomatik. @@ -237,7 +386,11 @@ Pointer hodisalari sichqoncha, touch va qalam hodisalarini bir vaqtda, yagona ko Pointer hodisalari sichqoncha hodisalarini kengaytiradi. Biz hodisa nomlarida `mouse` ni `pointer` bilan almashtirishimiz mumkin va kodimiz sichqoncha uchun ishlashda davom etishini, boshqa qurilma turlari uchun yaxshiroq qo'llab-quvvatlash bilan kutishimiz mumkin. +<<<<<<< HEAD Drag'n'droplar va brauzer o'zi hijack qilish va boshqarishga qaror qilishi mumkin bo'lgan murakkab touch o'zaro ta'sirlar uchun - hodisalarda standart harakatni bekor qilishni va biz ishtirok etadigan elementlar uchun CSS da `touch-events: none` o'rnatishni eslang. +======= +For drag'n'drops and complex touch interactions that the browser may decide to hijack and handle on its own - remember to cancel the default action on events and set `touch-action: none` in CSS for elements that we engage. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Pointer hodisalarining qo'shimcha qobiliyatlari: diff --git a/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html b/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html new file mode 100644 index 000000000..781016f52 --- /dev/null +++ b/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html @@ -0,0 +1,6 @@ + + + +
+
+
diff --git a/2-ui/3-event-details/6-pointer-events/slider-html.view/style.css b/2-ui/3-event-details/6-pointer-events/slider-html.view/style.css new file mode 100644 index 000000000..9b3d3b82d --- /dev/null +++ b/2-ui/3-event-details/6-pointer-events/slider-html.view/style.css @@ -0,0 +1,19 @@ +.slider { + border-radius: 5px; + background: #E0E0E0; + background: linear-gradient(left top, #E0E0E0, #EEEEEE); + width: 310px; + height: 15px; + margin: 5px; +} + +.thumb { + width: 10px; + height: 25px; + border-radius: 3px; + position: relative; + left: 10px; + top: -5px; + background: blue; + cursor: pointer; +} diff --git a/2-ui/3-event-details/6-pointer-events/slider.view/index.html b/2-ui/3-event-details/6-pointer-events/slider.view/index.html index 23d04b5fe..ab2e9eb5c 100644 --- a/2-ui/3-event-details/6-pointer-events/slider.view/index.html +++ b/2-ui/3-event-details/6-pointer-events/slider.view/index.html @@ -5,22 +5,45 @@
+

Mouse over here to see the date

+ diff --git a/2-ui/3-event-details/6-pointer-events/slider.view/style.css b/2-ui/3-event-details/6-pointer-events/slider.view/style.css index 477f024e8..3dcf50980 100644 --- a/2-ui/3-event-details/6-pointer-events/slider.view/style.css +++ b/2-ui/3-event-details/6-pointer-events/slider.view/style.css @@ -8,6 +8,7 @@ } .thumb { + touch-action: none; width: 10px; height: 25px; border-radius: 3px; diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index bb2eddc9c..9d9ace3e3 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -104,7 +104,11 @@ Shunday qilib, `event.code` kutilmagan joylashuv uchun noto'g'ri belgiga mos kel Joylashuvga bog'liq belgilarni ishonchli kuzatish uchun `event.key` yaxshiroq usul bo'lishi mumkin. +<<<<<<< HEAD Boshqa tomondan, `event.code` har doim bir xil bo'lib, jismoniy tugma joylashuviga bog'langanligining afzalligi bor, hatto tashrif buyuruvchi tillarni o'zgartirsa ham. Shuning uchun unga tayanadigan tezkor tugmalar til almashtirilgan holatda ham yaxshi ishlaydi. +======= +On the other hand, `event.code` has the benefit of staying always the same, bound to the physical key location. So hotkeys that rely on it work well even in case of a language switch. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Biz joylashuvga bog'liq tugmalarni qayta ishlamoqchimizmi? U holda `event.key` yo'li. @@ -135,21 +139,31 @@ Masalan, quyidagi `` telefon raqamini kutadi, shuning uchun raqamlar, `+` ```html autorun height=60 run ``` +<<<<<<< HEAD Diqqat qiling, `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V` kabi maxsus tugmalar kirishda ishlamaydi. Bu qat'iy filtr `checkPhoneKey` ning yon ta'siri. Uni biroz yumshatamiz: +======= +The `onkeydown` handler here uses `checkPhoneKey` to check for the key pressed. If it's valid (from `0..9` or one of `+-()`), then it returns `true`, otherwise `false`. + +As we know, the `false` value returned from the event handler, assigned using a DOM property or an attribute, such as above, prevents the default action, so nothing appears in the `` for keys that don't pass the test. (The `true` value returned doesn't affect anything, only returning `false` matters) + +Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, do not work in the input. That's a side effect of the strict filter `checkPhoneKey`. These keys make it return `false`. + +Let's relax the filter a little bit by allowing arrow keys `key:Left`, `key:Right` and `key:Delete`, `key:Backspace`: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```html autorun height=60 run @@ -157,7 +171,13 @@ function checkPhoneKey(key) { Endi o'qlar va o'chirish yaxshi ishlaydi. +<<<<<<< HEAD ...Lekin biz hali ham sichqonchani ishlatib va o'ng bosish + Joylashtirish orqali har qanday narsani kiritishimiz mumkin. Shuning uchun filtr 100% ishonchli emas. Biz uni shunday qoldirishimiz mumkin, chunki ko'p hollarda ishlaydi. Yoki muqobil yondashuv `input` hodisasini kuzatish bo'ladi -- u har qanday o'zgarishdan keyin ishga tushadi. U yerda biz yangi qiymatni tekshirishimiz va noto'g'ri bo'lganda uni ajratib ko'rsatish/o'zgartirishimiz mumkin. +======= +Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. Mobile devices provide other means to enter values. So the filter is not 100% reliable. + +The alternative approach would be to track the `oninput` event -- it triggers *after* any modification. There we can check the new `input.value` and modify it/highlight the `` when it's invalid. Or we can use both event handlers together. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Meros diff --git a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html index 6a571f1b2..fbcfdd168 100644 --- a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html +++ b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html @@ -26,11 +26,18 @@

Kirish maydoniga e'tibor qarating va tugmani bosing.

+<<<<<<< HEAD +======= + + + + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js index 212cc7056..5fd2f0f5d 100644 --- a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js +++ b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js @@ -5,6 +5,7 @@ let lastTime = Date.now(); function handle(e) { if (form.elements[e.type + "Ignore"].checked) return; +<<<<<<< HEAD let text = e.type + " key=" + @@ -16,6 +17,18 @@ function handle(e) { (e.altKey ? " altKey" : "") + (e.metaKey ? " metaKey" : "") + (e.repeat ? " (repeat)" : "") + +======= + area.scrollTop = 1e6; + + let text = e.type + + ' key=' + e.key + + ' code=' + e.code + + (e.shiftKey ? ' shiftKey' : '') + + (e.ctrlKey ? ' ctrlKey' : '') + + (e.altKey ? ' altKey' : '') + + (e.metaKey ? ' metaKey' : '') + + (e.repeat ? ' (repeat)' : '') + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 "\n"; if (area.value && Date.now() - lastTime > 250) { diff --git a/2-ui/4-forms-controls/1-form-elements/article.md b/2-ui/4-forms-controls/1-form-elements/article.md index 4d1a72253..f2a54d012 100644 --- a/2-ui/4-forms-controls/1-form-elements/article.md +++ b/2-ui/4-forms-controls/1-form-elements/article.md @@ -153,7 +153,11 @@ Forma boshqaruvlari haqida gaplashaylik. ### input va textarea +<<<<<<< HEAD Biz ularning qiymatiga `input.value` (string) yoki checkbox lar uchun `input.checked` (boolean) sifatida kirishimiz mumkin. +======= +We can access their value as `input.value` (string) or `input.checked` (boolean) for checkboxes and radio buttons. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Mana bunday: @@ -242,7 +246,11 @@ Bu sintaksis ixtiyoriy. Biz `document.createElement('option')` dan foydalanishim - `defaultSelected` -- agar `true` bo'lsa, `selected` HTML-atributi yaratiladi, - `selected` -- agar `true` bo'lsa, option tanlangan. +<<<<<<< HEAD `defaultSelected` va `selected` orasidagi farq shundaki, `defaultSelected` HTML-atributni o'rnatadi (uni `option.getAttribute('selected')` dan foydalanib olishimiz mumkin), `selected` esa option tanlanganligini yoki tanlanmaganligini belgilaydi. +======= +The difference between `defaultSelected` and `selected` is that `defaultSelected` sets the HTML-attribute (that we can get using `option.getAttribute('selected')`), while `selected` sets whether the option is selected or not. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Amalda, odatda ikkala qiymatni ham `true` yoki `false` ga o'rnatish kerak. (Yoki, shunchaki ularni o'tkazib yuborish; ikkalasi ham standart ravishda `false`.) diff --git a/2-ui/4-forms-controls/2-focus-blur/article.md b/2-ui/4-forms-controls/2-focus-blur/article.md index db0ad3865..b9230f998 100644 --- a/2-ui/4-forms-controls/2-focus-blur/article.md +++ b/2-ui/4-forms-controls/2-focus-blur/article.md @@ -89,8 +89,15 @@ Agar biz inputga biror narsa kiritsak va keyin `key:Tab` dan foydalanishga harak Diqqat qiling, `onblur` da `event.preventDefault()` ni chaqirish orqali "fokusni yo'qotishning oldini ololmaymiz", chunki `onblur` element fokusni yo'qotgandan *keyin* ishlaydi. +<<<<<<< HEAD ```warn header="JavaScript tomonidan boshlangan fokus yo'qolishi" Fokus yo'qolishi ko'p sabablarga ko'ra sodir bo'lishi mumkin. +======= +In practice though, one should think well, before implementing something like this, because we generally *should show errors* to the user, but *should not prevent their progress* in filling our form. They may want to fill other fields first. + +```warn header="JavaScript-initiated focus loss" +A focus loss can occur for many reasons. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ulardan biri tashrif buyuruvchi boshqa joyga bosganda. Lekin JavaScript ning o'zi ham bunga sabab bo'lishi mumkin, masalan: diff --git a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html index 2300bd2dd..5117e9ab6 100644 --- a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html +++ b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html @@ -130,8 +130,31 @@

Depozit kalkulyatori

return new Intl.NumberFormat("uz-UZ").format(amount) + " so'm"; } +<<<<<<< HEAD // Boshlang'ich hisoblash calculate(); +======= + let interest = form.interest.value * 0.01; + + if (!interest) return; + + let years = form.months.value / 12; + if (!years) return; + + let result = Math.round(initial * (1 + interest) ** years); + + let height = result / form.money.value * 100 + 'px'; + document.getElementById('height-after').style.height = height; + document.getElementById('money-before').innerHTML = form.money.value; + document.getElementById('money-after').innerHTML = result; + } + + calculate(); + + + + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md index 8b04c2a77..847480da5 100644 --- a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md +++ b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md @@ -15,8 +15,15 @@ Har qanday kirish o'zgarishi darhol qayta ishlanishi kerak. Formula quyidagicha: ```js +<<<<<<< HEAD // boshlang'ich: boshlang'ich pul summasi // qiziqish: masalan. 0,05 yiliga 5% degani // yillar: necha yil kutish kerak let result = Math.round(initial * (1 + interest * years)); +======= +// initial: the initial money sum +// interest: e.g. 0.05 means 5% per year +// years: how many years to wait +let result = Math.round(initial * (1 + interest) ** years); +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ``` diff --git a/2-ui/4-forms-controls/3-events-change-input/article.md b/2-ui/4-forms-controls/3-events-change-input/article.md index be6b88b6d..466269738 100644 --- a/2-ui/4-forms-controls/3-events-change-input/article.md +++ b/2-ui/4-forms-controls/3-events-change-input/article.md @@ -57,22 +57,36 @@ Shuning uchun biz u yerda `event.preventDefault()` dan foydalana olmaymiz -- bu Bu hodisalar qiymatni kesish/nusxalash/joylashtirish paytida sodir bo'ladi. +<<<<<<< HEAD Ular [ClipboardEvent](https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces) sinfiga tegishli va nusxalangan/joylashtirilgan ma'lumotlarga kirish imkonini beradi. +======= +They belong to [ClipboardEvent](https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces) class and provide access to the data that is cut/copied/pasted. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Harakatni bekor qilish uchun `event.preventDefault()` dan ham foydalanishimiz mumkin, shunda hech narsa nusxalanmaydi/joylanmaydi. +<<<<<<< HEAD Masalan, quyidagi kod barcha bunday hodisalarning oldini oladi va biz nima kesishga/nusxalashga/joylashtirshga harakat qilayotganimizni ko'rsatadi: +======= +For instance, the code below prevents all `cut/copy/paste` events and shows the text we're trying to cut/copy/paste: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ```html autorun height=40 run ``` +<<<<<<< HEAD Diqqat qiling, nafaqat matn, balki hamma narsani nusxalash/joylashtirish mumkin. Masalan, biz OS fayl menejerida faylni nusxalashimiz va uni joylashtirshimiz mumkin. Buning sababi `clipboardData` odatda drag'n'drop va nusxalash/joylashtirish uchun ishlatiladigan `DataTransfer` interfeysini amalga oshiradi. Bu hozir bizning qamrov doiramizdan biroz tashqarida, lekin siz uning metodlarini [spetsifikatsiyada](https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface) topishingiz mumkin. @@ -82,6 +96,31 @@ Clipboard "global" OS darajasidagi narsa. Shuning uchun ko'pgina brauzerlar xavf Shuningdek, Firefox bundan mustasno barcha brauzerlarda `dispatchEvent` bilan "maxsus" clipboard hodisalarini yaratish taqiqlangan. ``` +======= +Please note: inside `cut` and `copy` event handlers a call to `event.clipboardData.getData(...)` returns an empty string. That's because technically the data isn't in the clipboard yet. If we use `event.preventDefault()` it won't be copied at all. + +So the example above uses `document.getSelection()` to get the selected text. You can find more details about document selection in the article . + +It's possible to copy/paste not just text, but everything. For instance, we can copy a file in the OS file manager, and paste it. + +That's because `clipboardData` implements `DataTransfer` interface, commonly used for drag'n'drop and copy/pasting. It's a bit beyond our scope now, but you can find its methods in the [DataTransfer specification](https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface). + +Also, there's an additional asynchronous API of accessing the clipboard: `navigator.clipboard`. More about it in the specification [Clipboard API and events](https://www.w3.org/TR/clipboard-apis/), [not supported by Firefox](https://caniuse.com/async-clipboard). + +### Safety restrictions + +The clipboard is a "global" OS-level thing. A user may switch between various applications, copy/paste different things, and a browser page shouldn't see all that. + +So most browsers allow seamless read/write access to the clipboard only in the scope of certain user actions, such as copying/pasting etc. + +It's forbidden to generate "custom" clipboard events with `dispatchEvent` in all browsers except Firefox. And even if we manage to dispatch such event, the specification clearly states that such "synthetic" events must not provide access to the clipboard. + +Even if someone decides to save `event.clipboardData` in an event handler, and then access it later -- it won't work. + +To reiterate, [event.clipboardData](https://www.w3.org/TR/clipboard-apis/#clipboardevent-clipboarddata) works solely in the context of user-initiated event handlers. + +On the other hand, [navigator.clipboard](https://www.w3.org/TR/clipboard-apis/#h-navigator-clipboard) is the more recent API, meant for use in any context. It asks for user permission, if needed. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Xulosa @@ -89,6 +128,12 @@ Ma'lumot o'zgarishi hodisalari: | Hodisa | Tavsif | Xususiyatlar | |---------|----------|-------------| +<<<<<<< HEAD | `change`| Qiymat o'zgartirildi. | Matn inputlari uchun fokus yo'qotilganda ishga tushadi. | | `input` | Matn inputlari uchun har o'zgarishda. | `change` dan farqli o'laroq darhol ishga tushadi. | -| `cut/copy/paste` | Kesish/nusxalash/joylashtirish harakatlari. | Harakatning oldini olish mumkin. `event.clipboardData` xossasi clipboard ga o'qish/yozish kirishini beradi. | \ No newline at end of file +| `cut/copy/paste` | Kesish/nusxalash/joylashtirish harakatlari. | Harakatning oldini olish mumkin. `event.clipboardData` xossasi clipboard ga o'qish/yozish kirishini beradi. | +======= +| `change`| A value was changed. | For text inputs triggers on focus loss. | +| `input` | For text inputs on every change. | Triggers immediately unlike `change`. | +| `cut/copy/paste` | Cut/copy/paste actions. | The action can be prevented. The `event.clipboardData` property gives access to the clipboard. All browsers except Firefox also support `navigator.clipboard`. | +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/2-ui/5-loading/01-onload-ondomcontentloaded/article.md b/2-ui/5-loading/01-onload-ondomcontentloaded/article.md index ba2f159e4..b0c584a55 100644 --- a/2-ui/5-loading/01-onload-ondomcontentloaded/article.md +++ b/2-ui/5-loading/01-onload-ondomcontentloaded/article.md @@ -2,9 +2,15 @@ HTML sahifaning hayot tsikli uchta muhim hodisaga ega: +<<<<<<< HEAD - `DOMContentLoaded` -- brauzer HTML ni to'liq yukladi va DOM daraxti qurildi, lekin tashqi resurslar (rasmlar `` va stil fayllari) hali yuklanmagandir. - `load` -- nafaqat HTML, balki barcha tashqi resurslar ham yuklandi: rasmlar, stillar va boshqalar. - `beforeunload/unload` -- foydalanuvchi sahifani tark etmoqda. +======= +- `DOMContentLoaded` -- the browser fully loaded HTML, and the DOM tree is built, but external resources like pictures `` and stylesheets may not yet have loaded. +- `load` -- not only HTML is loaded, but also all the external resources: images, styles etc. +- `beforeunload/unload` -- the user is leaving the page. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Har bir hodisa foydali bo'lishi mumkin: @@ -85,7 +91,11 @@ Lekin bu yerda tuzoq bor. Agar stildan keyin skript bo'lsa, u holda skript stil ```html ``` @@ -110,8 +120,13 @@ Quyidagi misol rasm o'lchamlarini to'g'ri ko'rsatadi, chunki `window.onload` bar ```html diff --git a/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html b/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html index bd5bc0c45..950c848cb 100644 --- a/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html +++ b/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html @@ -1,5 +1,6 @@ +<<<<<<< HEAD @@ -12,6 +13,20 @@ [40] tayyor holat: tugallangan [40] img yuklash [40] oynani yuklash +======= + + + + +
diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 9d2ad3912..637830fa0 100644 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -131,7 +131,17 @@ Async skriptlar sahifaga mustaqil uchinchi tomon skriptlarini: hisoblagichlar, r ``` +<<<<<<< HEAD ## Dinamik skriptlar +======= +```smart header="The `async` attribute is only for external scripts" +Just like `defer`, the `async` attribute is ignored if the ` + + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 flyjet.classList.add("growing"); }; diff --git a/7-animation/2-css-animations/3-animate-circle/solution.view/index.html b/7-animation/2-css-animations/3-animate-circle/solution.view/index.html index 2ab19e761..66762b302 100644 --- a/7-animation/2-css-animations/3-animate-circle/solution.view/index.html +++ b/7-animation/2-css-animations/3-animate-circle/solution.view/index.html @@ -14,10 +14,26 @@ +<<<<<<< HEAD +======= + + + + +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 +``` + +Here's a more complex example, with `@keyframes`: + +```html run height=80 autorun no-beautify +

click me to start / stop

+ +``` + +## Summary + +CSS animations allow smoothly (or step-by-step) animated changes of one or multiple CSS properties. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Ular ko'pchilik animatsiya vazifalari uchun yaxshi. Shuningdek, biz animatsiyalar uchun JavaScript'dan foydalanishimiz mumkin, keyingi bob bunga bag'ishlangan. @@ -421,6 +610,12 @@ JavaScript animatsiyalariga nisbatan CSS animatsiyalarining cheklovlari: - Faqat xususiyat o'zgarishlari emas. Biz JavaScript'da animatsiyaning bir qismi sifatida yangi elementlar yaratishimiz mumkin. ``` +<<<<<<< HEAD Animatsiyalarning aksariyati ushbu bobda tasvirlanganidek CSS yordamida amalga oshirilishi mumkin. Va `transitionend` hodisasi animatsiyadan keyin JavaScript'ni ishga tushirish imkonini beradi, shuning uchun u kod bilan yaxshi integratsiya qilinadi. +======= +In early examples in this chapter, we animate `font-size`, `left`, `width`, `height`, etc. In real life projects, we should use `transform: scale()` and `transform: translate()` for better performance. + +The majority of animations can be implemented using CSS as described in this chapter. And the `transitionend` event allows JavaScript to be run after the animation, so it integrates fine with the code. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Lekin keyingi bobda biz murakkabroq holatlarni qamrab olish uchun JavaScript animatsiyalarini qilamiz. \ No newline at end of file diff --git a/7-animation/3-js-animation/1-animate-ball/solution.view/index.html b/7-animation/3-js-animation/1-animate-ball/solution.view/index.html index 3c2226b09..1ed6b8d35 100644 --- a/7-animation/3-js-animation/1-animate-ball/solution.view/index.html +++ b/7-animation/3-js-animation/1-animate-ball/solution.view/index.html @@ -22,6 +22,7 @@ }; } +<<<<<<< HEAD function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { @@ -30,6 +31,12 @@ Math.pow(b, 2) ); } +======= + function bounce(timeFraction) { + for (let a = 0, b = 1; 1; a += b, b /= 2) { + if (timeFraction >= (7 - 4 * a) / 11) { + return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 } } diff --git a/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html b/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html index ae1684fed..7ea27e121 100644 --- a/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html +++ b/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html @@ -22,6 +22,7 @@ }; } +<<<<<<< HEAD function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { @@ -30,6 +31,12 @@ Math.pow(b, 2) ); } +======= + function bounce(timeFraction) { + for (let a = 0, b = 1; 1; a += b, b /= 2) { + if (timeFraction >= (7 - 4 * a) / 11) { + return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 } } diff --git a/7-animation/3-js-animation/article.md b/7-animation/3-js-animation/article.md index d48d2ff21..6f8ad03b3 100644 --- a/7-animation/3-js-animation/article.md +++ b/7-animation/3-js-animation/article.md @@ -79,7 +79,11 @@ Bu bir nechta mustaqil qayta chizishlar birlashtirilishi kerak, brauzer uchun qa Yodda tutish kerak bo'lgan yana bir narsa bor. Ba'zida CPU yuklanadi yoki kamroq tez qayta chizish uchun boshqa sabablar bor (masalan, brauzer yorlig'i yashiringanda), shuning uchun biz uni har `20ms`da ishlatmasligimiz kerak. +<<<<<<< HEAD Lekin buni JavaScript-da qanday bilamiz? [Animation timing](http://www.w3.org/TR/animation-timing/) spetsifikatsiyasi mavjud bo'lib, u `requestAnimationFrame` funksiyasini taqdim etadi. U bu barcha masalalarni va undan ham ko'pini hal qiladi. +======= +But how do we know about that in JavaScript? There's a specification [Animation timing](https://www.w3.org/TR/animation-timing/) that provides the function `requestAnimationFrame`. It addresses all these issues and even more. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Sintaksis: ```js @@ -96,7 +100,11 @@ Qaytarilgan qiymat `requestId` chaqiruvni bekor qilish uchun ishlatilishi mumkin cancelAnimationFrame(requestId); ``` +<<<<<<< HEAD `callback` bitta argumentni oladi -- sahifa yuklanishining boshlanishidan o'tgan vaqt mikrosoniyalarda. Bu vaqtni [performance.now()](mdn:api/Performance/now) ni chaqirish orqali ham olish mumkin. +======= +The `callback` gets one argument -- the time passed from the beginning of the page load in milliseconds. This time can also be obtained by calling [performance.now()](mdn:api/Performance/now). +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 Odatda `callback` juda tez ishlaydi, CPU yuklanmagan yoki noutbukning batareyasi deyarli tugamagan yoki boshqa sabab bo'lmasa. @@ -159,7 +167,11 @@ function animate({timing, draw, duration}) { } ``` +<<<<<<< HEAD Uning grafigi: +======= + Its graph: +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ![](linear.svg) Bu `transition-timing-function: linear` kabi. Quyida ko'rsatilgan qiziqarli variantlar bor. @@ -282,7 +294,7 @@ Tasavvur qiling, biz to'pni tashlaymiz. U pastga tushadi, keyin bir necha marta ```js function bounce(timeFraction) { - for (let a = 0, b = 1, result; 1; a += b, b /= 2) { + for (let a = 0, b = 1; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) } @@ -451,4 +463,8 @@ Albatta biz uni yaxshilashimiz, ko'proq xususiyatlar qo'shishimiz mumkin, lekin JavaScript animatsiyalari har qanday timing funksiyasidan foydalanishi mumkin. Biz ularni yanada ko'p qirrali qilish uchun ko'plab misollar va transformatsiyalarni ko'rib chiqdik. CSS dan farqli o'laroq, biz bu yerda Bezier egri chiziqlari bilan cheklanmaymiz. -`draw` haqida ham xuddi shunday: biz CSS xususiyatlari emas, balki har qanday narsani animatsiya qilishimiz mumkin. \ No newline at end of file +<<<<<<< HEAD +`draw` haqida ham xuddi shunday: biz CSS xususiyatlari emas, balki har qanday narsani animatsiya qilishimiz mumkin. +======= +The same is true about `draw`: we can animate anything, not just CSS properties. +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 diff --git a/7-animation/3-js-animation/bounce-easeinout.view/index.html b/7-animation/3-js-animation/bounce-easeinout.view/index.html index aba658f6a..9d519c013 100644 --- a/7-animation/3-js-animation/bounce-easeinout.view/index.html +++ b/7-animation/3-js-animation/bounce-easeinout.view/index.html @@ -19,6 +19,7 @@ }; } +<<<<<<< HEAD function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { @@ -27,6 +28,13 @@ Math.pow(b, 2) ); } +======= + + function bounce(timeFraction) { + for (let a = 0, b = 1; 1; a += b, b /= 2) { + if (timeFraction >= (7 - 4 * a) / 11) { + return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 } } diff --git a/7-animation/3-js-animation/bounce-easeout.view/index.html b/7-animation/3-js-animation/bounce-easeout.view/index.html index 8ee866d69..71c12250f 100644 --- a/7-animation/3-js-animation/bounce-easeout.view/index.html +++ b/7-animation/3-js-animation/bounce-easeout.view/index.html @@ -18,6 +18,7 @@ }; } +<<<<<<< HEAD function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { @@ -26,6 +27,12 @@ Math.pow(b, 2) ); } +======= + function bounce(timeFraction) { + for (let a = 0, b = 1; 1; a += b, b /= 2) { + if (timeFraction >= (7 - 4 * a) / 11) { + return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 } } diff --git a/7-animation/3-js-animation/bounce.view/index.html b/7-animation/3-js-animation/bounce.view/index.html index 820a43cc5..d9fff5209 100644 --- a/7-animation/3-js-animation/bounce.view/index.html +++ b/7-animation/3-js-animation/bounce.view/index.html @@ -11,6 +11,7 @@
+<<<<<<< HEAD diff --git a/8-web-components/1-webcomponents-intro/article.md b/8-web-components/1-webcomponents-intro/article.md index e1cfd7140..fcb578204 100644 --- a/8-web-components/1-webcomponents-intro/article.md +++ b/8-web-components/1-webcomponents-intro/article.md @@ -26,9 +26,15 @@ Xalqaro Kosmik Stansiya: ...Va bu narsa uchadi, odamlarni kosmosda tirik saqlaydi! +<<<<<<< HEAD Bunday murakkab qurilmalar qanday yaratiladi? Bizning ishlab chiqishimizni bir xil darajada ishonchli va kengaytiriladigan qilish uchun qaysi prinsiplarni qarz olishimiz mumkin? Yoki hech bo'lmaganda unga yaqin. +======= +How are such complex devices created? + +Which principles could we borrow to make our development same-level reliable and scalable? Or, at least, close to it? +>>>>>>> 51bc6d3cdc16b6eb79cb88820a58c4f037f3bf19 ## Komponent arxitekturasi diff --git a/8-web-components/4-template-element/article.md b/8-web-components/4-template-element/article.md index 151ebf17f..372a8e96e 100644 --- a/8-web-components/4-template-element/article.md +++ b/8-web-components/4-template-element/article.md @@ -2,7 +2,11 @@ O'rnatilgan `