Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Type Coercion (Ép kiểu ngầm) trong JavaScript

Type Coercion là việc JavaScript **tự động chuyển đổi kiểu dữ liệu** khi thực hiện phép toán giữa các kiểu khác nhau. Khác với Type Casting (ép kiểu tường minh do dev chủ động).

Quy tắc chính:

  • + với string → **concatenation** (nối chuỗi), ép kiểu toán hạng còn lại thành string
  • -, *, /, % → **ép kiểu thành Number**
  • == (loose equality) → ép kiểu cả hai về cùng kiểu rồi so sánh
  • === (strict equality) → **KHÔNG** ép kiểu

Ví dụ minh họa

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Type Coercion JS</title>
  <style>
    body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
    .sample { font-size: 20px; font-weight: 500; margin: 10px 0; color: red; }
    .result { font-size: 18px; font-weight: 500; margin: 10px 0; color: green; }
    button { padding: 8px 16px; cursor: pointer; }
    table { border-collapse: collapse; width: 100%; margin-top: 20px; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: center; }
    th { background: #f5f5f5; }
  </style>
</head>
<body>
  <h1>JavaScript Type Coercion (Ép kiểu ngầm)</h1>
  <div class="sample" id="sample">22</div>
  <div class="result" id="result"></div>
  <button class="Btn" id="btn">NHẤN VÀO ĐÂY</button>
  <h3> Nhấn nút để cộng số 22 (string) với 5 (number) </h3>
  <script>
    const sampleEle = document.querySelector('#sample');
    const resEle = document.querySelector("#result");
    
    document.querySelector("#btn").addEventListener("click", () => {
      const str = sampleEle.innerHTML; // "22"
      const num = 5;
      
      // Type Coercion: String + Number -> String
      const result = str + num; // "22" + 5 -> "225"
      
      resEle.innerHTML = `
        Expression: "22" + 5
Kết quả: "${result}" (${typeof result})
Giải thích: Toán tử + với string → concatenation, ép 5 thành "5" `; // Bảng so sánh coercion let tableHtml = '

Bảng Type Coercion phổ biến:

'; const cases = [ ['"22" + 5', '"22" + 5', 'String + Number → String'], ['"22" - 5', '"22" - 5', 'String - Number → Number'], ['"22" * 5', '"22" * 5', 'String * Number → Number'], ['"22" / 5', '"22" / 5', 'String / Number → Number'], ['true + 1', 'true + 1', 'Boolean + Number → Number'], ['false + 1', 'false + 1', 'Boolean + Number → Number'], ['null + 1', 'null + 1', 'Null + Number → Number'], ['undefined + 1', 'undefined + 1', 'Undefined + Number → NaN'], ['[] + 1', '[] + 1', 'Array + Number → String'], ['[1] + 2', '[1] + 2', 'Array + Number → String'], ['{} + 1', '{} + 1', 'Object + Number → String (hoặc syntax error)'], ['"hello" + []', '"hello" + []', 'String + Array → String'], ]; cases.forEach(([expr, desc, type]) => { try { // eslint-disable-next-line no-eval const result = eval(expr); tableHtml += ``; } catch (e) { tableHtml += ``; } }); tableHtml += '
Biểu thứcKết quảLoại coercion
${expr}${JSON.stringify(result)}${type}
${expr}Error: ${e.message}
'; resEle.innerHTML += tableHtml; }); </script> </body> </html>

Kết quả

Expression: "22" + 5
Kết quả: "225" (string)
Giải thích: Toán tử + với string → concatenation, ép 5 thành "5"

Bảng Type Coercion chi tiết:

Biểu thứcKết quảGiải thích
"22" + 5"225"String + Number → String concat
"22" - 517String - Number → Number
"22" * "2"44String * String → Number
true + 12Boolean → Number (true=1)
false + 11Boolean → Number (false=0)
null + 11Null → Number (0)
undefined + 1NaNUndefined → Number (NaN)
[] + 1"1"Array → "" (empty string) + "1"
[1,2] + 3"1,23"Array → "1,2" + "3"
{} + 11 hoặc "[object Object]1"Context dependent (block vs expression)

== vs === (Loose vs Strict Equality):

// Loose equality (==) - CÓ coercion
1 == "1"        // true
true == 1       // true
false == 0      // true
null == undefined // true
"" == 0         // true
[] == 0         // true
[] == ""        // true

// Strict equality (===) - KHÔNG coercion
1 === "1"       // false
true === 1      // false
null === undefined // false

Best Practice:

  • Luôn dùng === và !== (trừ khi có lý do cụ thể dùng ==)
  • Ép kiểu tường minh trước khi so sánh: Number(input) === 5
  • ESLint rule: eqeqeq: ["error", "always"]
  • Hiểu coercion để debug, không để nó "lén lút" trong code