อธิบายลูป for…in ของ JavaScript: ไวยากรณ์, การใช้งาน, และแนวปฏิบัติที่ดีที่สุด

目次

1. บทนำ|ปัญหาอะไรที่คำสั่ง for…in สามารถแก้ได้?

JavaScript เป็นหนึ่งในภาษาการเขียนโปรแกรมที่ใช้กันอย่างแพร่หลายที่สุดในการพัฒนาเว็บ. ในคุณสมบัติมากมายของมัน, การวนลูป เป็นสิ่งจำเป็นสำหรับการประมวลผลข้อมูลซ้ำ ๆ. โดยเฉพาะอย่างยิ่ง, คำสั่ง for…in มีประโยชน์สำหรับการวนซ้ำผ่านคุณสมบัติของอ็อบเจกต์.

จุดประสงค์ของบทความนี้

ในบทความนี้เราจะครอบคลุมประเด็นต่อไปนี้อย่างละเอียด:

  • ไวยากรณ์พื้นฐานและการใช้งานของลูป for…in ใน JavaScript
  • ข้อควรระวังเมื่อใช้กับอาร์เรย์
  • ความแตกต่างเมื่อเทียบกับโครงสร้างลูปอื่น ๆ (for…of และ forEach)
  • ข้อผิดพลาดทั่วไปและวิธีแก้

สิ่งที่คุณจะได้เรียนรู้

  • วิธีประมวลผลคุณสมบัติของอ็อบเจกต์และสมาชิกของอาร์เรย์อย่างมีประสิทธิภาพ
  • ข้อควรระวังและการใช้คำสั่ง for…in อย่างปลอดภัย
  • ตัวอย่างโค้ดเชิงปฏิบัติและการเปรียบเทียบประสิทธิภาพ

บทความนี้จัดโครงสร้างเพื่อให้ความรู้ที่เป็นประโยชน์แก่ทั้งผู้เริ่มต้นและนักพัฒนา JavaScript ระดับกลาง. เรามาเริ่มในส่วนต่อไปด้วยพื้นฐานของ for…in กันเถอะ.

2. คำสั่ง for…in ของ JavaScript คืออะไร?【คำอธิบายพื้นฐาน】

ใน JavaScript, คำสั่ง for…in ใช้เพื่อวนซ้ำผ่านคุณสมบัติของอ็อบเจกต์. ไวยากรณ์นี้เหมาะอย่างยิ่งกับอ็อบเจกต์, ทำให้คุณสามารถประมวลผลชื่อคุณสมบัติ (คีย์) ทีละหนึ่งได้.

ไวยากรณ์พื้นฐาน

นี่คือไวยากรณ์พื้นฐานของลูป for…in:

for (variable in object) {
  // Repeated processing
}

คำอธิบายพารามิเตอร์:

  • variable : เก็บชื่อคุณสมบัติปัจจุบัน (คีย์).
  • object : อ็อบเจกต์เป้าหมายที่คุณต้องการวนซ้ำ.

ตัวอย่างการใช้งาน: การแสดงรายการคุณสมบัติของอ็อบเจกต์

const person = {
  name: "Taro",
  age: 25,
  city: "Tokyo"
};

for (const key in person) {
  console.log(`${key}: ${person[key]}`);
}

ผลลัพธ์:

name: Taro
age: 25
city: Tokyo

คำเต ลำดับของคุณสมบัติที่แสดงรายการ

ลำดับของคุณสมบัติในลูป for…in ไม่ได้รับการรับประกัน. ตามสเปคของ JavaScript, ลำดับอาจไม่ตรงกับลำดับการแทรก เมื่อคีย์เป็นสตริง. หากคุณต้องการลำดับที่เข้มงวด, ให้ใช้วิธีอื่นเช่น Object.keys().

สรุปคุณลักษณะ

  1. ดึงคีย์ของอ็อบเจกต์ได้ง่าย: มีประโยชน์เมื่อเข้าถึงชื่อคุณสมบัติแบบไดนามิก.
  2. เฉพาะคุณสมบัติที่เป็น enumerable เท่านั้นที่ถูกเลือก: คุณสมบัติที่ไม่เป็น enumerable ( enumerable: false ) จะถูกละเว้น.
  3. คุณสมบัติที่สืบทอดจาก prototype ก็จะถูกแสดงรายการด้วย: สิ่งนี้อาจทำให้เกิดปัญหา, ซึ่งจะอธิบายในส่วนต่อไป.

3. อาร์เรย์และคำสั่ง for…in|จุดสำคัญที่ควรระวัง

คำสั่ง for…in ของ JavaScript ถูกออกแบบมาเพื่อแสดงรายการคุณสมบัติของอ็อบเจกต์, แต่ก็สามารถใช้กับอาร์เรย์ได้. อย่างไรก็ตาม, มีข้อควรระวังหลายประการเมื่อใช้กับอาร์เรย์. มาดูพฤติกรรมและข้อผิดพลาดอย่างละเอียดกัน.

พฤติกรรมพื้นฐานกับอาร์เรย์

พิจารณาตัวอย่างต่อไปนี้:

const fruits = ["Apple", "Banana", "Orange"];

for (const index in fruits) {
  console.log(index, fruits[index]);
}

ผลลัพธ์:

0 Apple  
1 Banana  
2 Orange

คำเตือน 1: คุณสมบัติจาก Prototype อาจถูกแสดงรายการ

Array.prototype.newMethod = function () {
  return "New Method";
};

for (const index in fruits) {
  console.log(index, fruits[index]);
}

ผลลัพธ์:

0 Apple  
1 Banana  
2 Orange  
newMethod undefined

วิธีแก้ไข:

for (const index in fruits) {
  if (fruits.hasOwnProperty(index)) {
    console.log(index, fruits[index]);
  }
}

คำเตือน 2: ลำดับไม่รับประกัน

const data = [];
data[10] = "Apple";
data[1] = "Banana";
data[5] = "Orange";

for (const index in data) {
  console.log(index, data[index]);
}

ผลลัพธ์:

1 Banana  
5 Orange  
10 Apple

คำเตือน 3: ดัชนีถูกจัดเป็นสตริง

const numbers = [10, 20, 30];
for (const index in numbers) {
  console.log(typeof index); // "string"
}

วิธีแก้ไข:

for (const index in numbers) {
  const numIndex = parseInt(index, 10);
  console.log(numIndex, numbers[numIndex]);
}

สรุป

  • ประโยค for…in เหมาะสำหรับออบเจ็กต์มากกว่าอาร์เรย์
  • สำหรับการจัดการลำดับและดัชนีตัวเลข for…of หรือ ลูป for แบบดั้งเดิม ได้รับการแนะนำ

4. ความแตกต่างระหว่าง for…in และ for…of【ตารางเปรียบเทียบ】

ใน JavaScript ทั้ง for…in และ for…of สามารถใช้สำหรับลูปได้ แต่กรณีการใช้งานและพฤติกรรมแตกต่างกัน

การเปรียบเทียบไวยากรณ์

for…in:

const obj = { a: 1, b: 2, c: 3 };
for (const key in obj) {
  console.log(key); // Retrieves keys
}

for…of:

const arr = [10, 20, 30];
for (const value of arr) {
  console.log(value); // Retrieves values
}

ตารางเปรียบเทียบ

Aspectfor…infor…of
TargetObjects and arraysArrays and iterable objects
OutputProperty names (keys)Values themselves
Prototype EnumerationMay include prototype propertiesDoes not enumerate prototype properties
Order GuaranteeNot guaranteedGuaranteed

ตัวอย่างปฏิบัติ|การจัดการอาร์เรย์

const arr = ['a', 'b', 'c'];

// for...in
for (const index in arr) {
  console.log(index); // Output: 0, 1, 2
}

// for...of
for (const value of arr) {
  console.log(value); // Output: 'a', 'b', 'c'
}

สรุป

  • for…in: ดีที่สุดสำหรับการจัดการคีย์ออบเจ็กต์
  • for…of: ดีที่สุดสำหรับอาร์เรย์และออบเจ็กต์ที่สามารถทำซ้ำได้

5. การใช้งานจริง: การประยุกต์ใช้และแนวปฏิบัติที่ดีที่สุดของประโยค for…in

ที่นี่ เราจะสำรวจการประยุกต์ใช้จริงของ ประโยค for…in ใน JavaScript และแนะนำแนวปฏิบัติที่ดีที่เป็นประโยชน์ในการพัฒนาจริง

1. ตัวอย่างที่ 1|การกรองคุณสมบัติออบเจ็กต์

const user = {
  name: "Tanaka",
  age: 30,
  email: "tanaka@example.com",
  password: "secret123"
};

const publicData = {};
for (const key in user) {
  if (key !== "password") {
    publicData[key] = user[key];
  }
}
console.log(publicData);

ผลลัพธ์:

{ name: 'Tanaka', age: 30, email: 'tanaka@example.com' }

2. ตัวอย่างที่ 2|การประมวลผลออบเจ็กต์แบบซ้อน

const data = {
  user: {
    name: "Sato",
    info: {
      age: 28,
      city: "Osaka"
    }
  }
};

function printNested(obj) {
  for (const key in obj) {
    if (typeof obj[key] === "object") {
      printNested(obj[key]);
    } else {
      console.log(`${key}: ${obj[key]}`);
    }
  }
}

printNested(data);

ผลลัพธ์:

name: Sato
age: 28
city: Osaka

3. แนวปฏิบัติที่ดี|การยกเว้นคุณสมบัติต้นแบบ

const obj = { a: 1, b: 2 };
Object.prototype.c = 3;

for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(`${key}: ${obj[key]}`);
  }
}

ผลลัพธ์:

a: 1
b: 2

สรุป

  • เราได้แนะนำกรณีการใช้งานที่เหมาะสมสำหรับการกรองและการจัดการออบเจ็กต์แบบซ้อน
  • ใช้ hasOwnProperty() เพื่อป้องกันไม่ให้มีการสืบทอดจากต้นแบบที่ไม่ตั้งใจถูกแจกแจง

6. ข้อผิดพลาดทั่วไปและวิธีแก้ไขกับ for…in【สำหรับผู้เริ่มต้น】

1. ตัวอย่างข้อผิดพลาดที่ 1|คุณสมบัติต้นแบบถูกแจกแจง

const obj = { a: 1, b: 2 };
Object.prototype.c = 3;

for (const key in obj) {
  console.log(key, obj[key]);
}

ผลลัพธ์:

a 1
b 2
c 3

วิธีแก้ไข:

for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key]);
  }
}

2. ตัวอย่างข้อผิดพลาดที่ 2|การใช้ for…in กับอาร์เรย์

const arr = [10, 20, 30];
Array.prototype.extra = "Additional Data";

for (const index in arr) {
  console.log(index, arr[index]);
}

ผลลัพธ์:

0 10
1 20
2 30
extra undefined

วิธีแก้ไข:

for (const value of arr) {
  console.log(value);
}

3. ตัวอย่างข้อผิดพลาดที่ 3|การจัดการค่าที่ไม่กำหนด

const obj = { a: 1, b: undefined, c: 3 };

for (const key in obj) {
  console.log(key, obj[key]);
}

วิธีแก้ไข:

for (const key in obj) {
  const value = obj[key] ?? "Default Value";
  console.log(key, value);
}

สรุป

  • ปัญหาคุณสมบัติต้นแบบ: ใช้ hasOwnProperty()
  • การจัดการอาร์เรย์: ชอบ for…of หรือ forEach แทน for…in
  • ค่าที่ไม่กำหนด: กำหนดค่าดีฟอลต์ด้วยตัวดำเนินการรวมแบบ nullish ( ?? )

7. การทดสอบประสิทธิภาพและทางเลือกอื่นของ for…in

1. การเปรียบเทียบประสิทธิภาพ

ประโยค for…in:

const obj = { a: 1, b: 2, c: 3 };
console.time("for...in");
for (const key in obj) {
  console.log(key, obj[key]);
}
console.timeEnd("for...in");

Object.keys():

console.time("Object.keys");
Object.keys(obj).forEach(key => {
  console.log(key, obj[key]);
});
console.timeEnd("Object.keys");

2. ผลลัพธ์การรียบเทียบตัวอย่าง

for...in: 0.015ms
Object.keys: 0.005ms

3. ตัวเลือกที่แนะนำ

  • การจัดการ Object: ควรใช้ Object.keys() เพื่อประสิทธิภาพและความปลอดภัยที่ดีกว่า
  • การจัดการ Array: ใช้ for…of หรือ forEach เพื่อการทำงานที่เร็วและเชื่อถือได้มากขึ้น

สรุป

  • คำสั่ง for…in สะดวก แต่ควรเลือกโครงสร้างลูปที่เหมาะสมที่สุดโดยคำนึงถึงประสิทธิภาพและความปลอดภัย

8. สรุป|ทำความเข้าใจคำสั่ง for…in และขั้นตอนต่อไป

1. ประเด็นสำคัญที่ควรจำ

  1. ไวยากรณ์พื้นฐานและการใช้งานของ for…in:
  • ใช้เพื่อวนซ้ำชื่อคุณสมบัติของอ็อบเจ็กต์
  • เน้นการทำงานกับคีย์ของอ็อบเจ็กต์ ไม่ใช่กับอาเรย์
  1. ข้อควรระวังเมื่อใช้กับอาเรย์:
  • ลำดับการวนไม่รับประกัน และอาจรวมคุณสมบัติจากโซ่ prototype ด้วย
  • สำหรับอาเรย์ ควรใช้ for…of หรือ forEach() แทน
  1. ความแตกต่างระหว่าง for…in และ for…of:
  • for…in: วนซ้ำชื่อคุณสมบัติ (คีย์)
  • for…of: วนซ้ำค่าจริงของอาเรย์หรืออ็อบเจ็กต์ที่เป็น iterable
  1. การใช้งานจริงและแนวปฏิบัติที่ดีที่สุด:
  • จัดการอ็อบเจ็กต์ซ้อนกันด้วยการเรียกซ้ำ (recursion)
  • ยกเว้นคุณสมบัติที่สืบทอดจาก prototype ด้วย hasOwnProperty()
  • ปรับปรุงประสิทธิภาพและความปลอดภัยด้วย Object.keys() หรือ Object.entries()
  1. การเพิ่มประสิทธิภาพ:
  • แนะนำให้ใช้ Object.keys() + forEach() เพื่อรับประกันลำดับและประสิทธิภาพ ทำให้เป็นทางเลือกที่ปลอดภัยกว่า for…in

2. คำตอบสำหรับคำถามที่พบบ่อย

Q1. ควรหลีกเลี่ยงการใช้คำสั่ง for…in หรือไม่?

  • A: คำสั่งนี้เหมาะกับการแสดงรายการคุณสมบัติของอ็อบเจ็กต์ แต่สำหรับอาเรย์หรืองานที่ต้องการประสิทธิภาพสูง ควรใช้ for…of หรือ Object.keys() แทน เนื่องจากปลอดภัยและมีประสิทธิภาพมากกว่า

Q2. คุณสมบัติจาก prototype จะถูกวนเสมอหรือไม่?

  • A: ใช่ ตามสเปคจะรวมคุณสมบัติที่สืบทอดจาก prototype ด้วย ใช้ hasOwnProperty() เพื่อตัดคุณสมบัติเหล่านั้นออก

Q3. ควรใช้ลูปแบบไหนสำหรับอาเรย์และอ็อบเจ็กต์?

  • อ็อบเจ็กต์: ใช้ for…in หรือ Object.keys()
  • อาเรย์: ใช้ for…of หรือ forEach()

3. ขั้นตอนต่อไป|สิ่งที่ควรเรียนรู้ต่อ

  1. Iterables และ Iterable Objects:
  • โครงสร้างข้อมูลเช่น Map, Set, WeakMap, WeakSet และวิธีวนลูปกับพวกมัน
  1. ฟังก์ชันระดับสูงสำหรับการจัดการข้อมูล:
  • การใช้งานจริงของ map(), filter(), reduce()
  1. เทคนิคขั้นสูงสำหรับ Object และ Array:
  • ใช้ Object.values() และ Object.entries() เพื่อประมวลผลข้อมูลอย่างมีประสิทธิภาพ
  1. ฟีเจอร์ส:
  • ฟีเจอร์ ES6+ เช่น spread operator และ destructuring เพื่อโค้ดที่อ่านง่ายขึ้น
  1. การเขียนโปรแกรมแบบอะซิงโครนัสด้วย Promise/Async/Await:
  • นำลูปไปใช้ในกระบวนการเรียกข้อมูลแบบเรียลไทม์และการจัดการอ็อบเจ็กต์แบบไดนามิก

4. ความคิดสุดท้าย|การเชี่ยวชาญลูปใน JavaScript

ในบทความนี้ เราได้มุ่งเน้นที่คำสั่ง for…in ของ JavaScript ครอบคลุมการใช้งานพื้นฐาน การประยุกต์สูง จุดอ่อนและทางเลือกที่ดีกว่า
ประเด็นสำคัญที่สุด:

  • for…in เหมาะกับการแสดงรายการคุณสมบัติของอ็อบเจ็กต์ แต่สำหรับอาเรย์หรือกรณีที่ต้องการประสิทธิภาพ ควรใช้วิธีอื่นแทน
  • ปฏิบัติตามแนวปฏิบัติที่ดีที่สุดและมาตรการความปลอดภัยเสมอ เพื่อหลีกเลี่ยงข้อผิดพลาดและพฤติกรรมที่ไม่คาดคิดในโค้ดของคุณ

ขั้นตอนต่อไป!
ขยายความเข้าใจเกี่ยวกับวิธีการทางเลือกและฟังก์ชันระดับสูง เพื่อยกระดับทักษะ JavaScript ของคุณให้ก้าวไกลยิ่งขึ้น.

広告