Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

ทำไมควรหลีกเลี่ยง ++ และ -- ใน JavaScript

Operator ++ และ -- ควรหลีกเลี่ยงเพราะอาจให้ผลลัพธ์ไม่คาดคิด เนื่องจาก precedence, side effects, และความสับสนระหว่าง prefix/postfix

ตัวอย่างปัญหาจากบทความ

<html>
  <body>
    <script>
      var a = 5;
      var b = ++a;  // b = 6, a = 6
      var c = a++;  // c = 6, a = 7
      var d = ++c;  // d = 7, c = 7
      
      document.write(a); // 7
      document.write("\r" + b); // 6
      document.write("\r" + c); // 7
      document.write("\r" + d); // 7
    </script>
  </body>
</html>

ปัญหา Whitespace

a = b = c = 1;
++a;    // a = 2
b--;    // b = 0 (post-decrement)
c;      // c = 1

// แต่ถ้าเขียน:
a = b = c = 1;
++ a;   // ยังคงเป็น ++a (whitespace ไม่ส่งผลในที่นี้)
// แต่บางกรณีอาจสับสน:
x = 5;
y = x++ + ++x; // สับสนมาก! หลีกเลี่ยง

ปัญหาทั่วไป

1. Confusion ใน Expression

let x = 5;
let y = x++ + ++x; // ไม่ชัดเจนว่า y = ?
// ขึ้นอยู่กับ order of evaluation

2. Side Effects ใน Function Call

function foo(val) {
  return val * 2;
}

let i = 0;
foo(i++); // ส่ง 0, i กลายเป็น 1
foo(++i); // ส่ง 2, i กลายเป็น 2

3. ใน Array Index

let arr = [1, 2, 3];
let i = 0;
console.log(arr[i++]); // 1 (index 0)
console.log(arr[++i]); // 3 (index 2, ข้าม 1!)

แนวทางปฏิบัติที่ดีกว่า

1. แยก Statement

// แทน
arr[i++] = value;

// ใช้
arr[i] = value;
i++;

2. ใช้ for...of หรือ forEach

// แทน for loop ด้วย index
for (let i = 0; i < arr.length; i++) { }

// ใช้
for (const item of arr) { }
arr.forEach(item => { });

3. ใช้ Functional Methods

// map, filter, reduce ไม่ต้องจัดการ index เอง
const doubled = arr.map(x => x * 2);
const evens = arr.filter(x => x % 2 === 0);

ESLint Rule

// .eslintrc
{
  "rules": {
    "no-plusplus": "error" // หรือ "warn"
  }
}

// อนุญาตใน for loop
{
  "rules": {
    "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }]
  }
}

สรุป

ใช้ i += 1 หรือ i = i + 1 แทน i++ / ++i ใน expression ที่ซับซ้อน
ใช้ for...of, forEach, map แทน loop ด้วย index