Type Coercion — avtomatik tur o'zgartirish va uning xavflari
Muammodan boshlaylik
console.log([] + []); // "" — bo'sh string
console.log([] + {}); // "[object Object]"
console.log({} + []); // 0 yoki "[object Object]" — kontekstga qarab!
console.log(+""); // 0
console.log(+null); // 0
console.log(+undefined);// NaN
console.log(+"3"); // 3
Bu natijalar tasodifiy emas — JavaScript ning type coercion qoidalari. Tushunmasangiz, bu xatolar sizni soatlab ovora qiladi.
Type Coercion nima?
Type Coercion — JavaScript ning bir turni boshqa turga avtomatik aylantirishi. Siz aytmaysiz, JavaScript o'zi qiladi.
Hayotiy o'xshatma: do'konda sotuvchi. Siz "besh" desangiz — u "5 so'm" deb tushunadi. "Bir yarim" desangiz — "1.5" deb tushunadi. Sotuvchi sizning so'zingizni raqamga "aylantiradi". Bu qulay, lekin ba'zan noto'g'ri tushunadi.
Ikki xil coercion bor:
Implicit — JavaScript o'zi, avtomatik qiladi. Explicit — siz o'zingiz, ataylab qilasiz.
Explicit coercion — ataylab aylantirish
Bu xavfsiz — siz nazorat qilasiz.
String ga aylantirish
String(123) // "123"
String(true) // "true"
String(null) // "null"
String(undefined)// "undefined"
String([1,2,3]) // "1,2,3"
(123).toString() // "123"
123 + "" // "123" — implicit, lekin ko'p ishlatiladi
Number ga aylantirish
Number("123") // 123
Number("") // 0 ← diqqat!
Number(" ") // 0 ← diqqat!
Number("abc") // NaN
Number(true) // 1
Number(false) // 0
Number(null) // 0 ← diqqat!
Number(undefined)// NaN
Number([]) // 0 ← diqqat!
Number([3]) // 3
Number([1,2]) // NaN
parseInt("123px") // 123 — raqam qismini oladi
parseFloat("3.14") // 3.14
+"123" // 123 — unary + operatori
Boolean ga aylantirish
Boolean(0) // false
Boolean("") // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(NaN) // false
// Qolgan hamma narsa — true
Boolean(1) // true
Boolean("0") // true ← "0" string, bo'sh emas!
Boolean([]) // true ← bo'sh massiv ham true!
Boolean({}) // true
Implicit coercion — avtomatik aylantirish
Bu xavfli — JavaScript o'zi qiladi, siz kutmagan natija chiqishi mumkin.
+ operatori bilan
+ ikki xil ishlaydi: raqam qo'shish yoki string birlashtirish. Qaysi biri? Operandlardan biri string bo'lsa — birlashtirish.
1 + 2 // 3 — ikkalasi number
1 + "2" // "12" — biri string, birlashtirish
"1" + 2 // "12"
1 + 2 + "3" // "33" — 1+2=3, keyin 3+"3"="33"
"1" + 2 + 3 // "123" — "1"+2="12", keyin "12"+3="123"
-, *, / operatorlari bilan
Bu operatorlar faqat raqam bilan ishlaydi — string ni raqamga aylantiradi:
"5" - 2 // 3 — "5" → 5
"5" * 2 // 10
"5" / 2 // 2.5
"abc" - 1 // NaN — "abc" raqamga aylanmaydi
Taqqoslashda
"5" > 3 // true — "5" → 5
"10" > 9 // true — "10" → 10
"10" > "9" // false — string taqqoslash: "1" < "9"
null > 0 // false
null == 0 // false
null >= 0 // true ← g'alati! null >= 0 true, lekin null > 0 false
null >= 0 nima uchun true? >= operatori null ni 0 ga aylantiradi: 0 >= 0 = true. Lekin == da maxsus qoida: null faqat undefined ga teng.
Ob'ekt va massivlar coercion da
Ob'ekt yoki massiv string/number kerak bo'lgan joyda ishlatilsa — JavaScript ularni aylantiradi.
[] + [] // "" — ikkalasi "" ga aylanadi, "" + "" = ""
[] + {} // "[object Object]" — [] → "", {} → "[object Object]"
[1] + [2] // "12" — [1] → "1", [2] → "2"
+[] // 0 — [] → "" → 0
+[1] // 1 — [1] → "1" → 1
+[1,2] // NaN — [1,2] → "1,2" → NaN
Nima uchun [] → ""? Massiv string ga aylantirilganda join(",") chaqiriladi. Bo'sh massiv — bo'sh string.
Nima uchun {} → "[object Object]"? Ob'ekt string ga aylantirilganda toString() chaqiriladi — natija "[object Object]".
== va coercion
== operatori turlarni avtomatik aylantiradi — shu sababli xavfli:
false == 0 // true — false → 0
false == "" // true — false → 0, "" → 0
false == "0" // false — false → 0, "0" → 0... lekin "0" → 0, 0 == 0 = true?
// aslida: false → 0, "0" string qoladi, 0 == "0" → 0 == 0 = true
// yo'q: false == "0" → 0 == "0" → 0 == 0 = true...
// JavaScript spec: false → 0, keyin 0 == "0" → 0 == 0 = true
Bu qoidalarni yodlash shart emas — === ishlatilsa muammo yo'q.
Tez-tez uchraydigan xatolar
Forma inputidan kelgan qiymatni raqam deb hisoblash:
const input = document.getElementById("age").value; // "25" — string!
const nextAge = input + 1; // "251" — string birlashtirish!
const nextAge = Number(input) + 1; // ✅ 26
const nextAge = +input + 1; // ✅ 26
null ni raqam bilan hisoblash:
let count = null;
count += 1; // 1 — null → 0, 0 + 1 = 1
// Bu ishlaydi, lekin niyat noto'g'ri — count undefined bo'lishi kerak edi
Bo'sh massivni false deb hisoblash:
const items = [];
if (!items) {
console.log("bo'sh"); // ❌ ishlamaydi — [] truthy!
}
if (items.length === 0) {
console.log("bo'sh"); // ✅
}
parseInt ni Number o'rnida ishlatish:
parseInt(null) // NaN — to'g'ri
parseInt(undefined) // NaN — to'g'ri
parseInt("") // NaN — to'g'ri
Number("") // 0 — kutilmagan
Number(null) // 0 — kutilmagan
Foydalanuvchi inputi uchun parseInt yoki parseFloat ishonchli — bo'sh string va null uchun NaN qaytaradi, 0 emas.
Xulosa
Type Coercion — JavaScript ning bir turni boshqa turga avtomatik aylantirishi.
Explicit (ataylab): Number(), String(), Boolean(), parseInt() — xavfsiz, siz nazorat qilasiz.
Implicit (avtomatik): + string bilan uchrashsa birlashtiradi; -, *, / string ni raqamga aylantiradi; == turlarni o'zgartiradi.
Asosiy qoidalar:
- Forma inputlari har doim string —
Number()bilan aylantiring ===ishlatilsa==ning coercion muammolari yo'q- Bo'sh massiv
[]— truthy, uzunliginilength === 0bilan tekshiring
Keyingi dars
6-dars: Shartlar — if/else, switch, ternary