Mundarija (38)
- Bu darsda
- 1. Nega bu kerak?
- 2. JavaScript va ECMAScript
- 2.1 Til va standart
- 2.2 ES6 va ES2015 — bitta narsa
- 2.3 Xronologiya: kursda nima qayerdan kelgan
- 3. TC39 bosqichlari
- 3.1 Taklifning yo'li
- 3.2 Qaysi bosqichdagini ishlatish mumkin?
- 4. Brauzerda bormi? Baseline, caniuse va MDN
- 4.1 Baseline
- 4.2 caniuse.com va MDN jadvali
- 4.3 Node.js alohida
- 5. Kodda tekshirish: feature detection
- 5.1 Metod bormi?
- 5.2 Sintaksisni bunday tekshirib bo'lmaydi
- 6. Polyfill
- 6.1 O'zimiz yozamiz
- 6.2 Tayyor polyfill: core-js
- 6.3 Nega o'rnatilgan prototipni o'zingiz o'zgartirmaysiz
- 7. Transpile: yangi sintaksis — eski sintaksis
- 7.1 Polyfill nimani qila olmaydi
- 7.2 Haqiqiy misol: Babel
- 8. browserslist: "qaysi brauzerlar?" savoliga bitta javob
- 9. Hujumchi nigohi
- 10. Ko'p uchraydigan xatolar
- 10.1 "Chrome'da ishlayapti — demak, hammada ishlaydi"
- 10.2 Sintaksisni if bilan "himoyalash"
- 10.3 2-bosqichdagi taklifni ishchi kodda ishlatish
- 10.4 Polyfill'ni shartsiz qo'shish
- 11. Mashqlar
- 1-mashq (oson): Nashr va bosqich
- 2-mashq (o'rta): Math.sumPrecise polyfill'i
- 3-mashq (qiyin): Sintaksis va metod
- 4-mashq: Vazifalar qadami — qaysi brauzerlarda ishlaydi?
- 12. Real ishda
- Xulosa
- Manbalar
JS versiyalari va brauzer mosligi: ES2015 dan ES2027 gacha, Baseline va polyfill
Qisqacha: JavaScript tili ECMAScript standarti bilan belgilanadi va har yili iyunda yangi nashr chiqadi: ES2026 — 2026-yil 30-iyunda tasdiqlandi. Yangi imkoniyat standartga kirishdan oldin TC39 qo'mitasida 0 dan 4 gacha bosqichdan o'tadi. Lekin standartda borligi — brauzerda borligi degani emas. Tekshirish: Baseline belgisi (web-features), caniuse.com, MDN jadvali. Yo'q bo'lsa: yetishmayotgan funksiyani polyfill qo'shadi (core-js), yangi sintaksisni esa transpiler eski sintaksisga aylantiradi (Babel, SWC). Qaysi brauzerlar uchun — browserslist aytadi.
Bu darsda
- JavaScript, ECMAScript, ES6 va ES2015 nomlari farqini va har yilgi nashr qanday chiqishini tushuntira olasiz.
- TC39 bosqichlari (0, 1, 2, 2.7, 3, 4) nima ekanini va qaysi bosqichdagi imkoniyatni ishlatish xavfsizligini bilasiz.
- Imkoniyat qaysi brauzerlarda borligini Baseline, caniuse va MDN orqali tekshirasiz.
- Kodda imkoniyat bor-yo'qligini tekshirasiz (feature detection) va o'zingiz kichik polyfill yozasiz.
- Polyfill va transpile farqini, core-js, Babel, SWC va browserslist vazifasini haqiqiy chiqishlarda ko'rasiz.
Oldin bilishingiz kerak: Veb standartlari va brauzer mosligi, Brauzer mosligi: Baseline, caniuse va @supports, npm ga birinchi qadam, Xususiyat deskriptorlari, O'rnatilgan prototiplar va wrapper obyektlar, JavaScript'ning mashhur tuzoqlari.
1. Nega bu kerak?
Sardor vazifalar dagi teglarni sanaydigan qatorni chiroyliroq yozmoqchi edi. Hozir u shunday:
sanoq.set(teg, (sanoq.get(teg) ?? 0) + 1);U ES2026 da yangi Map.prototype.getOrInsert metodi borligini o'qidi: "kalit bo'lsa — qiymatini qaytaradi, yo'q bo'lsa — qo'shib, keyin qaytaradi". Chrome'da sinab ko'rdi — ishladi. Keyin npm test ni ishga tushirdi:
TypeError: sanoq.getOrInsert is not a functionTarjimasi: "sanoq.getOrInsert — funksiya emas". Chrome 154 da metod bor, Node 24 da esa yo'q. Testlar Node'da ishlaydi — demak, yiqildi.
Bu birinchi holat emas. Promise yordamchilari darsida Promise.try Node 22 da yo'qligini ko'rgan edik. Lookahead va lookbehind darsida esa bitta (?<=...) eski iPhone'larda butun saytni sindirganini o'qigansiz.
Bu darsda uchta savolga javob beramiz. Yangi imkoniyat qayerdan keladi? Qaysi brauzerda borligini qanday bilaman? Yo'q bo'lsa nima qilaman?
2. JavaScript va ECMAScript
2.1 Til va standart
ECMAScript — JavaScript tilining rasmiy standarti, ya'ni "til qanday ishlashi kerak"ligini yozib qo'ygan hujjat. Uning raqami — ECMA-262, uni Ecma International tashkiloti nashr qiladi. JavaScript — shu standartning brauzerlar va Node'dagi amalga oshirilishi (implementation): standartda yozilgan qoidani o'z dvigatelida haqiqatan dastur qilib yozib chiqish. Chrome va Node'da bu ishni V8 dvigateli qiladi, Firefox'da — SpiderMonkey, Safari'da — JavaScriptCore.
O'xshatish: futbol qoidalari kitobi va har bir stadiondagi o'yin. Qoidalar bitta, stadionlar ko'p. Hamma stadion yangi qoidani bir kunda qabul qilmaydi.
Standartni TC39 qo'mitasi yozadi. Unda brauzer kompaniyalari (Google, Apple, Mozilla, Microsoft), boshqa kompaniyalar va mustaqil mutaxassislar bor. Ularning yig'ilishlari ochiq: qaydlari GitHub'da e'lon qilinadi.
2.2 ES6 va ES2015 — bitta narsa
Uzoq vaqt nashrlar raqam bilan atalgan: ES3 (1999), ES5 (2009). ES4 umuman chiqmagan — kelishuvga erisha olishmagan. 2015-yilda katta oltinchi nashr chiqdi: let, const, arrow funksiyalar, klasslar, modullar, Promise. Uni ES6 deb ham, ES2015 deb ham atashadi.
Shundan keyin TC39 tartibni o'zgartirdi: katta nashr o'rniga har yili kichik nashr. Nomi — yil bilan: ES2016, ES2017 … ES2026. Shu tartibda o'n bitta nashr chiqdi. Eski maqolalarda "ES7", "ES8" ni ko'rsangiz: ES7 = ES2016, ES8 = ES2017 (raqam + 2009).
Har nashr Ecma'ning bosh assambleyasida iyun oyida tasdiqlanadi. ES2025 — 2025-yil 25-iyunda, ES2026 — 2026-yil 30-iyunda (Ecma'ning 131-assambleyasi, Jeneva).
2.3 Xronologiya: kursda nima qayerdan kelgan
| Nashr | Asosiy imkoniyatlar | Kursda |
|---|---|---|
| ES2015 | let/const, arrow, klass, modul, Promise, Map/Set |
08–11 |
| ES2016 | includes, ** |
08 |
| ES2017 | async/await, Object.entries, padStart |
08, 11 |
| ES2018 | obyekt spread, for await, finally, lookbehind, \p{…} |
08, 11, 12 |
| ES2019 | flat/flatMap, Object.fromEntries, barqaror sort |
10 |
| ES2020 | ??, ?., BigInt, globalThis, import(), allSettled |
08, 10, 11 |
| ES2021 | ??=, replaceAll, Promise.any, WeakRef, 1_000 |
08, 10, 11 |
| ES2022 | top-level await, #private, at(), Object.hasOwn, cause |
10, 11 |
| ES2023 | toSorted, with, findLast |
10 |
| ES2024 | Object.groupBy, withResolvers, v flag |
10, 11, 12 |
| ES2025 | Set metodlari, iterator helpers, Promise.try, RegExp.escape, JSON modullar |
10, 11, 12 |
| ES2026 | getOrInsert, Math.sumPrecise, base64, Iterator.concat, Error.isError, Array.fromAsync |
shu dars |
| ES2027 | Temporal, using, iterator chunks/zip — hali loyiha |
10, 12 |
Jadval TC39'ning rasmiy ro'yxatidan olingan (tc39/proposals, "Finished Proposals", 2026-10-05). E'tibor bering: using va Temporal — ES2027 da. Ular 4-bosqichga yetgan, lekin nashr 2027-yil iyunida tasdiqlanadi.
Har nashr qanchalik "katta" bo'lgani — quyidagi grafikda. Har yili tugallangan takliflar soni:
| Nashr | 4-bosqichga yetganlar |
|---|---|
| 2 016 | 2 |
| 2 017 | 6 |
| 2 018 | 8 |
| 2 019 | 8 |
| 2 020 | 9 |
| 2 021 | 5 |
| 2 022 | 7 |
| 2 023 | 4 |
| 2 024 | 7 |
| 2 025 | 10 |
| 2 026 | 7 |
| 2 027 | 7 |
Manba: github.com/tc39/proposals — finished-proposals.md, 2026-10-05 holati; ES2027 — hozircha (nashr 2027-yil iyunida)
Nimaga qarang: nashrlar kichik va tekis — yiliga 4–10 ta imkoniyat. Bu ES2015 dagi "hammasi birdaniga" o'rniga tanlangan yo'l: brauzerlar yangilikni bosqichma-bosqich qo'shadi.
Tekshirib ko'ring: Maqolada "ES8 dagi
async/await" deb yozilgan. Bu qaysi yil nashri?
Javob
ES2017. Raqamli nom + 2009 = yil: 8 + 2009 = 2017. Jadvalda ham async/await — ES2017.
3. TC39 bosqichlari
3.1 Taklifning yo'li
Har yangi imkoniyat taklif (proposal) sifatida boshlanadi va bosqichma-bosqich ko'tariladi:
flowchart LR
S0["0: g'oya"] --> S1["1: muammo va yechim"]
S1 --> S2["2: qoralama"]
S2 --> S27["2.7: to'liq matn, testlar"]
S27 --> S3["3: brauzerlar qo'shmoqda"]
S3 --> S4["4: tugadi"]
S4 --> N["Iyundagi nashr"]- 0-bosqich — g'oya. Hech qanday majburiyat yo'q.
- 1-bosqich — muammo aniq yozilgan, taklifni olib boradigan mas'ul shaxs (champion — "himoyachi") bor, yechim izlanmoqda.
- 2-bosqich — qoralama: sintaksis va API tasvirlangan, misollar bor. Hali ko'p narsa o'zgarishi mumkin.
- 2.7-bosqich — keyinroq qo'shilgan oraliq qadam: standartga kiradigan matn (spetsifikatsiya) to'liq, tekshiruvchilar rozi. Endi rasmiy testlar yoziladi — ular Test262 deb ataladigan umumiy to'plamga qo'shiladi va har dvigatel o'zini shu testlar bilan tekshiradi.
- 3-bosqich — brauzerlar qo'shishni boshlaydi. Faqat amalda topilgan muammolar tufayli o'zgaradi.
- 4-bosqich — tugadi. Shart: kamida ikki mustaqil amalga oshirish testlardan o'tgan va amalda sinalgan. Keyingi iyundagi nashrga kiradi.
3.2 Qaysi bosqichdagini ishlatish mumkin?
Qoida oddiy:
- 4-bosqich — bemalol, lekin brauzerda borligini tekshirib (keyingi bo'lim).
- 3-bosqich — polyfill bilan, ehtiyotkorlik bilan. Masalan, Temporal uzoq vaqt 3-bosqichda turdi va shu davrda polyfill orqali ishlatildi.
- 0–2-bosqich — o'quv tajribasi uchun. Ishchi kodda — yo'q: taklif o'zgarishi yoki butunlay bekor bo'lishi mumkin. Masalan, Records & Tuples taklifi 2025-yilda qaytarib olindi (Immutability chuqur).
Barcha takliflar va ularning bosqichi — github.com/tc39/proposals da.
Tekshirib ko'ring: Blogda "yangi pipeline operatori
|>— 2-bosqichda" deb yozilgan. Univazifalarda ishlatasizmi?
Javob
Yo'q. 2-bosqich — qoralama: sintaksis hali o'zgarishi mumkin, hech bir brauzer uni standart holatda qo'llamaydi. Uni faqat transpiler orqali va tajriba sifatida sinash mumkin. Ishchi loyihada — 4-bosqich va brauzerlarda borligi tekshirilgan imkoniyatlar.
4. Brauzerda bormi? Baseline, caniuse va MDN
4.1 Baseline
Veb standartlari va brauzer mosligi darsida Baseline belgisi bilan tanishgan edik. Eslatib o'tamiz: u "bu imkoniyat asosiy brauzerlarning hammasida ishlaydimi?" savoliga bitta belgi bilan javob beradi. Uni W3C'dagi WebDX guruhi (brauzer kompaniyalari vakillari) yuritadi. Asosiy brauzerlar: Chrome, Edge, Firefox va Safari — kompyuterda va telefonda.
Uch holat bor:
| Holat | Ma'nosi | Ishlatish |
|---|---|---|
| Limited availability | kamida bitta asosiy brauzerda yo'q | polyfill yoki zaxira yo'l bilan |
| Newly available | oxirgi brauzer ham qo'shdi | yangi brauzerli auditoriyaga |
| Widely available | "yangi" bo'lganiga 30 oy o'tdi | bemalol |
Shu belgini MDN sahifalarining tepasida ko'rasiz (masalan, Object.groupBy sahifasida). Uning ma'lumotlari web-features npm paketida ochiq. Biz shu darsda 3.40.1 versiyasini ishlatdik (npm view web-features version, 2026-10-05):
// baseline.mjs — avval: npm i web-features@3.40.1
import { features } from "web-features";
for (const id of ["array-group", "set-methods", "getorinsert"]) {
const { name, status } = features[id];
console.log(name, status.baseline, status.baseline_low_date);
}Haqiqiy chiqish (Node 24.21):
Array grouping high 2024-03-05
Set methods low 2024-06-11
Map getOrInsert() low 2026-02-14high — Widely available, low — Newly available, false — Limited. Object.groupBy 2024-yil 5-martdan hamma asosiy brauzerda bor va 2026-yil sentabrdan "keng tarqalgan". getOrInsert esa 2026-yil fevralidan "yangi". Temporal — false: Safari'da hali yo'q (Temporal API darsida ko'rgan edik).
4.2 caniuse.com va MDN jadvali
- caniuse.com — imkoniyat nomini yozasiz, har brauzer versiyasi bo'yicha jadval chiqadi. Foydasi: "dunyodagi foydalanuvchilarning necha foizida ishlaydi" raqami (StatCounter ma'lumoti asosida).
- MDN — har metod sahifasining pastida "Browser compatibility" jadvali. Unda Node.js va Deno ham bor — server kodi uchun foydali.
Ikkalasi ham bir manbadan foydalanadi: brauzerlar mosligi ma'lumotlar bazasi (@mdn/browser-compat-data). Shuning uchun raqamlari odatda bir xil.
4.3 Node.js alohida
Node'da brauzer yo'q, lekin xuddi shu savol bor: Node qaysi V8 versiyasini ishlatadi? Node 24.21 da V8 13.6. Unda ES2026 ning bir qismi bor, bir qismi yo'q:
console.log(typeof Promise.try); // function
console.log(typeof RegExp.escape); // function
console.log(typeof Map.prototype.getOrInsert); // undefined
console.log(typeof Math.sumPrecise); // undefinedChrome 154 da to'rttasi ham function. Loyiha qaysi Node versiyasida ishlashini package.json dagi engines maydonida yozib qo'yish odat: "engines": { "node": ">=24" }.
5. Kodda tekshirish: feature detection
5.1 Metod bormi?
Feature detection (imkoniyatni aniqlash) — kodning o'zi "bu imkoniyat shu yerda bormi?" deb tekshiradi va shunga qarab yo'l tanlaydi. Brauzer nomini emas, imkoniyatning o'zini tekshiramiz.
const counts = new Map([["#bozor", 1]]);
function increment(tag) {
if (typeof counts.getOrInsert === "function") {
counts.set(tag, counts.getOrInsert(tag, 0) + 1);
} else {
counts.set(tag, (counts.get(tag) ?? 0) + 1);
}
}
increment("#bozor");
increment("#uy");
console.log(counts); // Map(2) { '#bozor' => 2, '#uy' => 1 }Natija Node 24 da ham (ikkinchi yo'l), Chrome 154 da ham (birinchi yo'l) bir xil. Boshqa shakllari: "groupBy" in Object, "BroadcastChannel" in globalThis.
5.2 Sintaksisni bunday tekshirib bo'lmaydi
Metod yo'q bo'lsa — undefined, uni tekshirsa bo'ladi. Yangi sintaksis esa boshqacha. Brauzer tanimagan sintaksisni ko'rsa, butun faylni o'qishdan bosh tortadi — SyntaxError. Fayldagi if ga navbat ham kelmaydi. Lookbehind'li regex eski Safari'da saytni aynan shunday sindirgan.
Chiqish yo'li — sintaksisni satr ichida, try bilan sinash:
function supportsLookbehind() {
try {
new RegExp("(?<=#)\\p{L}+", "u");
return true;
} catch {
return false;
}
}
console.log(supportsLookbehind()); // truenew RegExp naqshni ishlash paytida o'qiydi, shuning uchun xato catch ga tushadi. Lekin ?., ??, #private kabi tilning o'z sintaksisini bunday sinash noqulay. Ular uchun boshqa yechim bor — transpile («Transpile» bo'limi).
Tekshirib ko'ring: Nega
if (typeof Temporal !== "undefined")ishlaydi,if (brauzer === "Safari")esa yomon g'oya?
Javob
Birinchisi imkoniyatning o'zini tekshiradi: Safari ertaga Temporal'ni qo'shsa, kod o'zi yangi yo'lga o'tadi. Ikkinchisi brauzer nomiga bog'langan: Safari yangilangach ham eski yo'lda qoladi, boshqa "Temporal'siz" brauzerni esa umuman bilmaydi. Brauzer nomi (navigator.userAgent) ishonchsiz ham — uni o'zgartirish oson.
6. Polyfill
6.1 O'zimiz yozamiz
Polyfill — yetishmayotgan funksiya yoki metodni eski muhitga JavaScript bilan qo'shib qo'yadigan kod. Nomi — devordagi yoriqni to'ldiradigan qurilish shpaklyovkasidan (inglizcha "Polyfilla" brendi). Qoidasi: avval tekshir, yo'q bo'lsagina qo'sh.
if (typeof Map.prototype.getOrInsert !== "function") {
Object.defineProperty(Map.prototype, "getOrInsert", {
value(key, defaultValue) {
if (!this.has(key)) this.set(key, defaultValue);
return this.get(key);
},
writable: true,
configurable: true,
});
}
const counts = new Map();
for (const tag of ["#bozor", "#uy", "#bozor"]) {
counts.set(tag, counts.getOrInsert(tag, 0) + 1);
}
console.log(counts); // Map(2) { '#bozor' => 2, '#uy' => 1 }Qator-qator:
if (typeof … !== "function")— metod bo'lsa, hech narsa qilmaymiz. Brauzerning o'z (tezroq va to'g'riroq) versiyasi ishlaydi.Object.defineProperty— oddiyMap.prototype.getOrInsert = …emas. Sababi: oddiy tayinlash sanaladigan (enumerable) xususiyat yaratadi, o'rnatilgan metodlar esa sanalmaydi (Xususiyat deskriptorlari).enumerableni yozmasak —false.value(key, defaultValue)— metod.this— metod chaqirilganMap.
6.2 Tayyor polyfill: core-js
Har metodni o'zingiz yozish xavfli: standartdagi chegaraviy holatlarni o'tkazib yuborish oson. Shuning uchun tayyor to'plam ishlatiladi. Eng mashhuri — core-js (shu dars yozilganda 3.50.0). U ES2027 gacha deyarli hamma narsani qoplaydi:
// core-js-sinov.mjs — avval: npm i core-js@3.50.0
console.log(typeof Map.prototype.getOrInsert);
await import("core-js/actual/map/get-or-insert.js");
console.log(typeof Map.prototype.getOrInsert);Node 24.21 da haqiqiy chiqish:
undefined
functionFaqat kerakli metodni ulash mumkin (core-js/actual/map/get-or-insert.js) yoki hammasini (core-js/actual). Qo'lda tanlash shart emas — buni keyingi bo'limdagi vositalar avtomatik qiladi.
Ponyfill — polyfill'ning "yumshoq" varianti: global prototipga tegmaydi, oddiy funksiya sifatida import qilinadi (getOrInsert(counts, tag, 0)). Kutubxona yozsangiz — ponyfill ishlating: birovning sahifasidagi Map.prototype ni o'zgartirish sizning ishingiz emas.
6.3 Nega o'rnatilgan prototipni o'zingiz o'zgartirmaysiz
2018-yilda TC39 massivga flatten metodini qo'shmoqchi edi. Ma'lum bo'ldiki, eski MooTools kutubxonasi Array.prototype.flatten ni o'zicha, boshqacha qo'shgan ekan. Standart metod qo'shilsa, MooTools ishlatgan minglab eski saytlar sinardi. Natijada standartdagi nom o'zgartirildi — flat. Bu voqea "smooshgate" deb ataladi. 2014-yilda xuddi shu sabab bilan String.prototype.contains o'rniga includes tanlangan.
Saboq: o'rnatilgan prototipga faqat standartdagi metodni, standartdagi nom va xulq bilan, "yo'q bo'lsa" sharti bilan qo'shing. O'zingizning "foydali" metodingizni (Array.prototype.oxirgisi) — hech qachon.
Tekshirib ko'ring: Polyfill nega
if (typeof … !== "function")sharti bilan boshlanadi? Shartsiz qo'shsak nima yo'qotamiz?
Javob
Brauzerda metod bor bo'lsa, uning o'z versiyasi ishlashi kerak: u tezroq va standartning hamma chegaraviy holatlarini to'g'ri bajaradi. Shartsiz qo'shsak, sizning sodda (ehtimol xatoli) versiyangiz uni bosib ketadi — yangi brauzerda ham. Polyfill faqat "yoriq" bor joyni to'ldiradi.
7. Transpile: yangi sintaksis — eski sintaksis
7.1 Polyfill nimani qila olmaydi
Polyfill — JavaScript kodi, u faqat yetishmayotgan qiymat yoki metod qo'sha oladi. ?. yoki ?? esa metod emas — tilning grammatikasi. Uni tanimaydigan brauzer faylni o'qiy olmaydi, polyfill'ga navbat kelmaydi.
Transpile (transpilyatsiya) — kodni bir xil darajadagi boshqa kodga o'girish. Bizda: yangi sintaksisli JavaScript'ni eski brauzer tushunadigan JavaScript'ga. Buni qiladigan dastur — transpiler: Babel (8.0.6) va SWC (1.16.13, Rust'da yozilgan, ancha tez).
7.2 Haqiqiy misol: Babel
Kirish fayli:
const phone = customer?.phone ?? "yo'q";
const byType = Object.groupBy(menu, (t) => t.type);Babel sozlamasi (babel.config.json): nishon — Safari 13, polyfill'lar uchun babel-plugin-polyfill-corejs3 (1.0.0):
{
"presets": [["@babel/preset-env", { "targets": "safari 13" }]],
"plugins": [
[
"polyfill-corejs3",
{ "method": "usage-global", "version": "3.50" }
]
]
}npx babel src/menu.js ning haqiqiy chiqishi (o'qish oson bo'lishi uchun Prettier bilan 60 belgiga formatladik):
var _customer$phone, _customer;
import "core-js/modules/es.object.group-by.js";
const phone =
(_customer$phone =
(_customer = customer) === null || _customer === void 0
? void 0
: _customer.phone) !== null &&
_customer$phone !== void 0
? _customer$phone
: "yo'q";
const byType = Object.groupBy(menu, (t) => t.type);Ikki xil ish bo'ldi, ikkalasi ham ko'rinib turibdi:
- Transpile:
?.va??g'oyib bo'ldi. O'rniga —=== null || … === void 0tekshiruvlari.void 0—undefinedning eski, qisqa yozuvi. - Polyfill:
Object.groupByqatori o'zgarmadi — bu metod, sintaksis emas. Uning o'rniga fayl boshiga core-js'dan faqat shu metod ulandi.
Nishonni "chrome 120" ga o'zgartirsak, ?. va ?? o'zgarmay qoladi — Chrome 120 ularni biladi. Transpiler faqat kerakli joyni o'zgartiradi.
Tekshirib ko'ring: Babel
?.ni o'zgartirdi,Object.groupByqatorini esa yo'q. Nega?
Javob
?. — sintaksis: eski brauzer uni o'qiy olmaydi, shuning uchun uni eski yozuvga o'girish (transpile) kerak. Object.groupBy — oddiy metod chaqiruvi, eski brauzer bu qatorni o'qiy oladi, faqat metod yo'q. Uni polyfill hal qiladi — shuning uchun Babel fayl boshiga core-js'dan shu metodni uladi.
Diqqat: Babel 8 da
@babel/preset-envning eskiuseBuiltInsopsiyasi olib tashlangan. Eski maqoladagi sozlamani ko'chirsangiz, shunday xato chiqadi:The 'useBuiltIns' option has been removed. Please use babel-plugin-polyfill-corejs3 instead.— "useBuiltInsopsiyasi olib tashlandi, o'rniga babel-plugin-polyfill-corejs3 ishlating". Versiyaga bog'liq maslahat — eskiradigan maslahat.
Amalda Babel'ni o'zingiz kamdan-kam sozlaysiz: Vite kabi vositalar uni (yoki SWC'ni, yoki yana bir tez transpiler — esbuild'ni) ichida ishlatadi. Bu 16-qismda — Frontend asboblar zanjiri darsidan boshlab.
8. browserslist: "qaysi brauzerlar?" savoliga bitta javob
Babel ham, core-js plagini ham, CSS uchun Autoprefixer ham bir savolni so'raydi: "qaysi brauzerlarni qo'llaymiz?". Har biriga alohida yozmaslik uchun browserslist bor — bitta ro'yxat, hamma vosita o'qiydi. U package.json dagi "browserslist" maydonida yoki .browserslistrc faylida yoziladi.
Ro'yxat so'rov bilan yoziladi. Ularni terminalda sinash mumkin (browserslist 4.29.3, caniuse-lite 1.0.30001814):
npx browserslist --coverage "defaults"These browsers account for 84.65% of all users globallyTarjimasi: "bu brauzerlar dunyodagi barcha foydalanuvchilarning 84,65 foizini qamraydi". defaults — "0,5 foizdan ko'p ulushli, har birining oxirgi 2 versiyasi, Firefox ESR (korxonalar uchun uzoq qo'llab-quvvatlanadigan versiya), o'lik bo'lmaganlar". "O'lik" — 24 oydan beri yangilanmagan brauzer. Ro'yxatning o'zi (npx browserslist "defaults") — 35 qator, boshi:
and_chr 154
and_ff 157
and_qq 14.9
and_uc 15.5
android 154
chrome 154
chrome 153Yana bir foydali so'rov — Baseline bilan: "baseline widely available". U Safari'ni 17.4 gacha, Chrome'ni 123 gacha qamraydi (jami 134 qator) — ya'ni "Widely available" imkoniyatlar ishlaydigan brauzerlar. Uni batafsil Polyfill, browserslist va Baseline darsida ko'ramiz.
flowchart TD
B["browserslist: qaysi brauzerlar"] --> T["Babel / SWC: sintaksisni o'giradi"]
B --> P["core-js plagini: kerakli polyfill"]
B --> C["Autoprefixer: CSS prefikslari"]
T --> F["Eski brauzer ham o'qiy oladigan fayl"]
P --> F9. Hujumchi nigohi
Polyfill — saytingizda har bir mehmonning brauzerida ishlaydigan begona kod. Uni qayerdan olayotganingiz muhim.
Uzoq yillar ko'p saytlar polyfill'ni cdn.polyfill.io dan <script> bilan ulardi: xizmat brauzerga qarab kerakli polyfill'larni yuborardi. 2024-yil fevralida domen va loyiha yangi egaga — Funnull kompaniyasiga o'tdi. Iyun oyida Sansec xavfsizlik kompaniyasi xabar berdi: skript o'zgartirilgan va telefondagi mehmonlarni firibgar saytlarga yo'naltirmoqda. BleepingComputer ma'lumotiga ko'ra, 100 mingdan ortiq sayt zarar ko'rgan. Sayt egalari o'z kodida hech narsani o'zgartirmagan edi.
Himoya:
- polyfill'ni npm'dan aniq versiya bilan o'rnating va o'z saytingizdan bering (bundler orqali), begona CDN'dan emas;
- begona CDN'dan skript ulasangiz —
integrityatributi (SRI — Subresource Integrity, "yuklangan fayl butunligi") bilan: fayl bir bayt o'zgarsa ham brauzer uni ishlatmaydi; - kerak bo'lmagan polyfill'ni olib tashlang: bugun Baseline "Widely available" bo'lgan imkoniyat uchun polyfill — ortiqcha kod va ortiqcha xavf.
10. Ko'p uchraydigan xatolar
10.1 "Chrome'da ishlayapti — demak, hammada ishlaydi"
Yangi metodni faqat o'z brauzeringizda sinash. Testlar Node'da, mehmonlarning yarmi Safari'da.
MDN/Baseline'ni tekshiring, npm test ni ishga tushiring.
10.2 Sintaksisni if bilan "himoyalash"
if (yangiBrauzer) { const x = a ?? b; } — eski brauzer faylni umuman o'qiy olmaydi.
Sintaksis uchun — transpile; metod uchun — feature detection yoki polyfill.
10.3 2-bosqichdagi taklifni ishchi kodda ishlatish
Blogda ko'rgan yangi sintaksisni Babel plagini bilan darhol loyihaga qo'shish.
4-bosqich va Baseline. Undan oldingisi — tajriba uchun alohida papkada.
10.4 Polyfill'ni shartsiz qo'shish
Map.prototype.getOrInsert = function … — brauzerning o'z versiyasini sizning (ehtimol xatoli) versiyangiz bosib ketadi.
if (typeof … !== "function") va Object.defineProperty.
11. Mashqlar
1-mashq (oson): Nashr va bosqich
Javob bering:
toSortedqaysi nashrda kelgan?- Kamida nechta mustaqil amalga oshirish bo'lganda taklif 4-bosqichga o'tadi?
- Baseline "Widely available" bo'lishi uchun "Newly available" dan keyin necha oy o'tishi kerak?
Yechim
- ES2023 — "nusxa bilan o'zgartirish" metodlari (
toSorted,toReversed,with) shu yili kelgan. - Ikkita — ikki xil dvigatelda testlardan o'tgan va amalda sinalgan.
- 30 oy. Shu vaqt ichida ko'p foydalanuvchilar brauzerini yangilab ulguradi.
2-mashq (o'rta): Math.sumPrecise polyfill'i
Math.sumPrecise (ES2026) sonlar ro'yxatini yaxlitlash xatosisiz qo'shadi. Node 24 da u yo'q. Sodda polyfill yozing: yo'q bo'lsagina qo'shilsin, ichida oddiy reduce ishlatilsin (aniq algoritm emas — faqat shakl uchun). Keyin Math.sumPrecise([35000, 28000, 5000]) ni chiqaring. Ishora: «O'zimiz yozamiz» bo'limidagi Object.defineProperty; Math — oddiy obyekt.
Yechim
if (typeof Math.sumPrecise !== "function") {
Object.defineProperty(Math, "sumPrecise", {
value(numbers) {
return [...numbers].reduce((sum, n) => sum + n, -0);
},
writable: true,
configurable: true,
});
}
console.log(Math.sumPrecise([35000, 28000, 5000])); // 68000-0 dan boshlaganimiz — standartdagi kichik detal: bo'sh ro'yxat yig'indisi -0. Bu polyfill aniq emas: Math.sumPrecise([1e20, 0.1, -1e20]) haqiqiy metodda 0.1, bizda esa 0. Shuning uchun ishchi kodda o'zingiz yozgan "o'xshash" polyfill emas — core-js (core-js/actual/math/sum-precise.js).
3-mashq (qiyin): Sintaksis va metod
Quyidagi kod Safari 13 da ishlashi kerak. Har qatorda nima kerak: transpile, polyfill yoki hech narsa? Javobni jadval qilib yozing, keyin web-features yoki MDN'dan tekshiring.
const note = booking?.note ?? "";
const tags = note.match(/#\p{L}+/gu) ?? [];
const last = tags.at(-1);
const copy = structuredClone(booking);Yechim
| Qator | Nima | Nega |
|---|---|---|
?., ?? |
transpile | ES2020 sintaksisi, Safari 13.1 dan |
\p{L} + u |
hech narsa | ES2018, Safari 11.1 dan bor |
at(-1) |
polyfill | ES2022 metodi, Safari 15.4 dan |
structuredClone |
polyfill | brauzer API'si, Safari 15.4 dan |
structuredClone — ECMAScript emas, HTML standartidagi brauzer API'si. core-js uni ham qoplaydi (core-js/actual/structured-clone.js), lekin barcha holatlarni emas. Muhim saboq: "polyfill bilan hal bo'ladimi?" savoli "bu metodmi yoki sintaksismi?" savoliga bog'liq.
4-mashq: Vazifalar qadami — qaysi brauzerlarda ishlaydi?
vazifalar README'sida "qo'llab-quvvatlanadigan brauzerlar" yo'q. Uni o'lchab topamiz. kurs/mashqlar/12/41-moslik/ da npm init -y qiling, package.json ga "type": "module" qo'shing, npm i web-features@3.40.1 va moslik.mjs ni yozing. U vazifalar ishlatadigan oltita imkoniyatni (toSorted, Object.groupBy, Set.prototype.difference, AbortSignal.any, AbortSignal.timeout, BroadcastChannel) tekshirib, har brauzer uchun eng katta talab qilinadigan versiyani chiqarsin. Ishora: «Baseline» bo'limidagi kod; web-features id'lari — array-by-copy, array-group, set-methods, abortsignal-any, abortsignal-timeout, broadcast-channel.
Yechim
// moslik.mjs — vazifalar ishlatadigan imkoniyatlar qayerda bor?
import { features } from "web-features";
const FEATURES = [
"array-by-copy", // toSorted
"array-group", // Object.groupBy
"set-methods", // Set.prototype.difference
"abortsignal-any", // AbortSignal.any
"abortsignal-timeout", // AbortSignal.timeout
"broadcast-channel", // BroadcastChannel
];
const BROWSERS = ["chrome", "firefox", "safari"];
const minimum = { chrome: "0", firefox: "0", safari: "0" };
for (const id of FEATURES) {
const { name, status } = features[id];
const cells = BROWSERS.map((b) => `${b} ${status.support[b]}`);
console.log(`${name}: ${status.baseline} | ${cells.join(", ")}`);
for (const b of BROWSERS) {
const v = status.support[b];
if (parseFloat(v) > parseFloat(minimum[b])) minimum[b] = v;
}
}
console.log("Eng kichik talab:", minimum);Haqiqiy chiqish (web-features 3.40.1, Node 24.21):
Array by copy: high | chrome 110, firefox 115, safari 16
Array grouping: high | chrome 117, firefox 119, safari 17.4
Set methods: low | chrome 122, firefox 127, safari 17
AbortSignal.any(): high | chrome 116, firefox 124, safari 17.4
AbortSignal.timeout(): low | chrome 124, firefox 100, safari 16
BroadcastChannel: high | chrome 54, firefox 38, safari 15.4
Eng kichik talab: { chrome: '124', firefox: '127', safari: '17.4' }Xulosa: vazifalar Chrome 124+, Firefox 127+, Safari 17.4+ da ishlaydi. Ikkita imkoniyat hali "Newly available" (low): Set metodlari va AbortSignal.timeout. Ro'yxat to'liq emas (masalan #private maydonlar, modullar ham bor), lekin ular ancha eski — talabni oshirmaydi. parseFloat bilan versiya solishtirish soddalashtirilgan: "17.10" ni "17.4" dan kichik deb hisoblaydi. Haqiqiy loyihada buni browserslist qiladi.
git add 12/41-moslik/moslik.mjs 12/41-moslik/package.json
git commit -m "12/41: vazifalar brauzer mosligi o'lchovi"package-lock.json ni ham qo'shing; node_modules — .gitignore da.
12. Real ishda
- Har kuni: yangi metodni ishlatishdan oldin MDN sahifasining tepasidagi Baseline belgisiga qarash — 5 soniyalik odat.
- Loyiha sozlamasi:
package.jsonda"browserslist"va"engines"— jamoa uchun "qaysi muhitlarni qo'llaymiz" kelishuvi. Vite, Next.js kabi vositalar o'z standart nishonlariga ega va browserslist'ni o'qiydi. - Kutubxonalar: kutubxona mualliflari polyfill qo'shmaydi — bu ilova egasining ishi. Kutubxona README'sida "talab: Node 20+, ES2022" deb yoziladi.
- Intervyu: "Polyfill va transpile farqi nima?", "TC39 bosqichlari qanday?", "Babel nima qiladi?" — frontend intervyularida tez-tez so'raladi.
Xulosa
- ECMAScript — standart, JavaScript — uning amalga oshirilishi; ES2015 dan beri har yili iyunda nashr: ES2026 — 2026-yil 30-iyun.
- Taklif 0 → 1 → 2 → 2.7 → 3 → 4 bosqichdan o'tadi; ishchi kodda — 4-bosqich (3-bosqich — polyfill bilan, ehtiyotkorlik bilan).
- Standartda bor — brauzerda bor degani emas: Baseline (
web-features), caniuse, MDN; Node uchun — uning V8 versiyasi va sinov. - Metod yo'q bo'lsa — feature detection va polyfill (core-js); sintaksis yo'q bo'lsa — transpile (Babel, SWC).
- browserslist — "qaysi brauzerlar" degan bitta kelishuv, uni hamma vosita o'qiydi.
- Polyfill — begona kod: npm'dan aniq versiya bilan, o'z saytingizdan; begona CDN'dan — faqat SRI bilan.
Keyingi dars: Nozik xatolar: race condition, xotira sizishi, flaky test va Heisenbug — faqat ba'zan chiqadigan xatolarni takrorlash va ushlash.
Manbalar
- Ecma International: "131st General Assembly" (2026-06-30), ECMA-262 17-nashr — ecma-international.org
- TC39: "The TC39 Process" — tc39.es/process-document; "Finished Proposals" — github.com/tc39/proposals
- web-features va Baseline — web-platform-dx.github.io/web-features; MDN "Baseline" lug'ati — developer.mozilla.org
- Mathias Bynens, "#SmooshGate FAQ" (2018) — developer.chrome.com/blog/smooshgate
- Babel 8:
@babel/preset-envhujjati — babeljs.io/docs/babel-preset-env; core-js — github.com/zloirock/core-js; browserslist — github.com/browserslist/browserslist - Sansec, "Polyfill supply chain attack hits 100K+ sites" (2024-06-25) — sansec.io; BleepingComputer (2024-06-25)
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!