Prototiplar, meros

Tug'ma prototiplar

prototype xossasi JavaScript yadrosining o'zida keng qo'llaniladi. Barcha tug'ma (native) konstruktor funksiyalar โ€” Object, Array, Function, Number va boshqalar โ€” o'z prototype laridan foydalanadi. Aynan shu sababli obyektlar, massivlar va satrlarda ko'plab tayyor metodlar mavjud.

Object.prototype

Bo'sh obyekt yaratganimizda, u aslida bo'sh emas. let obj = {} yozuvi let obj = new Object() bilan bir xil, bu yerda Object โ€” tug'ma konstruktor funksiya. Uning Object.prototype si toString va boshqa metodlarga ega, ular meros orqali barcha obyektlarga o'tadi:

native-object.js
// natija shu yerda chiqadi

Demak, zanjir shunday: obj โ†’ Object.prototype โ†’ null. Object.prototype zanjirning eng tepasi โ€” uning prototipi null.

Boshqa tug'ma prototiplar

Array, Function, Number, String, Boolean kabi tug'ma obyektlar ham o'z metodlarini prototiplarida saqlaydi. Masalan, massiv yaratganimizda [1, 2, 3] aslida new Array(1, 2, 3) ga o'xshaydi va uning barcha metodlari Array.prototype da yashaydi:

native-array.js
// natija shu yerda chiqadi

Ba'zi metodlar turli prototiplarda takrorlanishi mumkin. Masalan, Array.prototype ning o'z toString i bor โ€” u massiv elementlarini vergul bilan ajratib qaytaradi. Object.prototype ning toString i esa [object Object] qaytaradi. Zanjir bo'ylab yaqinroqdagisi (Array'niki) ishlatiladi:

native-tostring.js
// natija shu yerda chiqadi
Funksiyalar ham obyekt โ€” ularning [[Prototype]] si Function.prototype bo'lib, u call, apply, bind kabi metodlarni beradi. Shu sababli istalgan funksiyada bu metodlar mavjud.

Primitivlar va prototiplar

Satr, son va mantiqiy qiymatlar (primitivlar) obyekt emas. Ammo biz ularning xossa yoki metodlariga murojaat qilsak (masalan, str.toUpperCase()), vaqtinchalik "o'ram" (wrapper) obyekt yaratiladi. U o'z ishini bajaradi va yo'qoladi. Bu o'ram obyektlarning metodlari ham prototiplarda joylashgan: String.prototype, Number.prototype, Boolean.prototype.

native-primitive.js
// natija shu yerda chiqadi
null va undefined ning o'ram obyektlari YO'Q โ€” ularda hech qanday metod yoki xossa yo'q. Ularga murojaat qilsangiz xato yuz beradi.

Tug'ma prototiplarni kengaytirish

Tug'ma prototiplarni o'zgartirish (kengaytirish) mumkin. Masalan, String.prototype ga yangi metod qo'shsak, u barcha satrlarda paydo bo'ladi:

native-extend.js
// natija shu yerda chiqadi

Bu kuchli, lekin XAVFLI imkoniyat. Prototiplar global (bir butun dastur uchun umumiy). Ikki xil kutubxona bir xil nomdagi metodni qo'shsa, biri ikkinchisini ustidan yozib, kutilmagan xatolarni keltirib chiqaradi.

Umumiy qoida: tug'ma prototiplarni kengaytirmang. Bu deyarli har doim yomon g'oya, chunki: 1) global konfliktlar; 2) kelajakda til aynan shu nomdagi standart metodni qo'shsa, sizning kodingiz uni buzadi; 3) kod o'qilishi qiyinlashadi.
Yagona maqbul istisno โ€” polyfill. Bu til standartida bor, lekin eski dvigatelda hali qo'llab-quvvatlanmagan metodni qo'lda amalga oshirishdir. Bunda avval metod mavjudligini tekshiramiz va faqat yo'q bo'lsa qo'shamiz.
native-polyfill.js
// natija shu yerda chiqadi

Prototiplardan qarz olish (borrowing)

Ba'zan bir tug'ma prototip metodini boshqa obyektga "qarzga" olamiz. Masalan, massivga o'xshash (array-like) obyektga Array.prototype metodlarini qo'llash mumkin:

native-borrow.js
// natija shu yerda chiqadi

Bu ishlaydi, chunki join ning ichki algoritmi faqat to'g'ri son indekslar va length xossasini kutadi โ€” obyekt haqiqiy massiv bo'lishini talab qilmaydi. Bu texnika "metod qarz olish" (method borrowing) deb ataladi.

Xulosa