Type Coercion — avtomatik tur o'zgartirish va uning xavflari

~15 daq · JavaScript · Kirish va Asoslar

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, uzunligini length === 0 bilan tekshiring

Keyingi dars

6-dars: Shartlar — if/else, switch, ternary