อะไรคือความแตกต่างระหว่าง (สำหรับ ... ใน) และ (สำหรับ ... ของ) งบใน JavaScript?


410

ฉันรู้ว่าfor... inลูปคืออะไร(มันวนซ้ำที่สำคัญ) แต่ได้ยินครั้งแรกเกี่ยวกับfor... of(มันวนซ้ำเกินมูลค่า)

ฉันสับสนกับfor... ofลูป ฉันไม่ได้รับคำคุณศัพท์ นี่คือรหัสด้านล่าง:

var arr = [3, 5, 7];
arr.foo = "hello";

for (var i in arr) {
  console.log(i); // logs "0", "1", "2", "foo"
}

for (var i of arr) {
  console.log(i); // logs "3", "5", "7"
  // it is does not log "3", "5", "7", "hello"
}

สิ่งที่ฉันได้รับคือทำfor... ofซ้ำมากกว่าค่าของคุณสมบัติ ถ้าอย่างนั้นทำไมมันไม่เข้าสู่ระบบ (กลับ) "3", "5", "7", "hello"แทน"3", "5", "7"? แต่for... inวนซ้ำทุกคีย์ ( "0", "1", "2", "foo") ที่นี่for... inวนซ้ำยังวนซ้ำที่fooสำคัญ แต่for... ofไม่ได้ย้ำกว่ามูลค่าของเช่นคุณสมบัติfoo "hello"ทำไมถึงเป็นเช่นนั้น

เรื่องสั้นในระยะสั้น:

ที่นี่ฉันfor... ofวนลูปคอนโซล มันควรเข้าสู่ระบบแต่ที่นี่มันล็อก"3", "5", "7","hello" "3", "5", "7"ทำไม

ลิงค์ตัวอย่าง


1
ในกรณีที่คุณพลาดนี่คือนักพัฒนา
Anthony Russell

1
เท่าที่ความเข้าใจของฉันfor ... ofถูกนำเข้าสู่ภาษาเพื่อแก้ไขปัญหาการใช้งานfor ... inกับอาร์เรย์ Array.prototypeอาจมีการแก้ไขในลักษณะที่มีคุณสมบัติเพิ่มเติมทำให้ไม่ปลอดภัยในการวนซ้ำเนื่องจากคุณอาจได้รับคีย์ตัวเลขที่คุณไม่ได้คาดหวัง
Phylogenesis

2
สำหรับผู้อ่านในอนาคต: นี่อาจจะไม่ซ้ำกับคำสำคัญJavaScript of(สำหรับ ... จากลูป)เนื่องจากมันถามเกี่ยวกับพฤติกรรมที่เฉพาะเจาะจงของคุณลักษณะแทนที่จะถามถึงภาพรวมทั่วไป
apsillers

2
เพิ่งได้ใช้ในการพูดว่า " for <key> in" และ " for <value> of" และตระหนักถึง IE ไม่ได้รับการสนับสนุนfor..of
BotNet

บทความที่ดีเกี่ยวกับmedium.com/@shivamethical/
Kalhan.Toress

คำตอบ:


304

for in วนซ้ำชื่อคุณสมบัติที่นับได้ของวัตถุ

for of(ใหม่ใน ES6) ใช้ตัววนซ้ำเฉพาะวัตถุและวนซ้ำค่าที่สร้างขึ้น

ในตัวอย่างของคุณตัวทำซ้ำอาร์เรย์จะให้ค่าทั้งหมดในอาร์เรย์ (ไม่สนใจคุณสมบัติที่ไม่ใช่ดัชนี)


9
for ... ofเป็นมาตรฐานใน ES6
Justin

2
แปลกมากฉันสาบานว่าฉันอ่านที่ไหนสักแห่งที่มันถูกย้ายกลับไปที่ ES7 แต่ดูเหมือนจะไม่จริง ความผิดฉันเอง.
Alexander O'Mara

40
ตัวช่วยความจำ: 'o'f -> ไม่' o'bjects, 'i'n -> ไม่ใช่' i'terables
Placoplatr

4
อีกช่วยในการจำ: for... of:: อาร์เรย์ :: อาร์เรย์มีความยาวเสมอดังนั้นคุณสามารถคิดว่าfor.. [องค์ประกอบที่ n] of.. [องค์ประกอบ q]
นาธานสมิ ธ

14
ช่วยในการจำอื่น ... for..in..keys=== กุญแจต่างประเทศ === ใช้for...inสำหรับกุญแจ! เช่นนี้ใช้for...ofสำหรับค่า
กุนเธอร์

237

ฉันพบคำตอบที่สมบูรณ์ได้ที่: https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html (แม้ว่าจะเป็นสคริปต์ประเภทนี้ก็เหมือนกันกับจาวาสคริปต์)

ทั้งสอง for..ofและfor..inงบซ้ำรายการ; ค่าที่ทำซ้ำจะแตกต่างกันไป แต่จะfor..inส่งคืนรายการของคีย์บนวัตถุที่ถูกทำซ้ำในขณะที่for..ofส่งคืนรายการค่าของคุณสมบัติตัวเลขของวัตถุที่ถูกทำซ้ำ

นี่คือตัวอย่างที่แสดงให้เห็นถึงความแตกต่างนี้:

let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}

ความแตกต่างอีกอย่างก็คือ .. ในการทำงานกับวัตถุใด ๆ มันทำหน้าที่เป็นวิธีการตรวจสอบคุณสมบัติบนวัตถุนี้ for..ofในทางกลับกันส่วนใหญ่มีความสนใจในคุณค่าของวัตถุที่ทำซ้ำได้ วัตถุในตัวเช่นแผนที่และการตั้งค่าimplement Symbol.iteratorคุณสมบัติช่วยให้สามารถเข้าถึงค่าที่เก็บไว้

let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";

for (let pet in pets) {
   console.log(pet); // "species"
}

for (let pet of pets) {
    console.log(pet); // "Cat", "Dog", "Hamster"
}

1
ยิ่งไปกว่านั้นการโทรหาบางสิ่งที่ต้องการ (ให้ฉันจาก {}) {console.log (i); } จะโยน TypeError: VM391: 1 Uncaught TypeError: {} ไม่สามารถทำซ้ำได้ที่ <anonymous>: 1: 14, อย่างน้อยใน Chrome
kboom

TS สำหรับผู้ชนะ - ตัวอย่างไม่ถูกต้องหลังควรส่งคืน "สัตว์เลี้ยงลูกด้วยนม" ไม่ใช่ // "แคท", "สุนัข", "แฮมสเตอร์"
martinp999

8
ผมจำได้ว่ามันโดย: สำหรับ "ใน" indexสำหรับ จากนั้นสำหรับ "ของ" จะเป็นvaluesของแต่ละดัชนี / คีย์ / รายการ
SherylHohman

Nice นี่จะเป็นราชาของฉัน: ใช้ for-ins สำหรับการวนซ้ำของรายการที่ฉันมักจะต้องสร้างlet thisItem = items[all];ตัวแปรfor...ofช่วยทางลัดนั้น!
Vasily Hall

ฉันจำได้โดย: for...inเป็นObject.keys()เดาอะไร อาเรย์คืออ็อบเจ๊กต์ซึ่งจะส่งคืนอนาจารด้วย :)
Sujeet Agrahari

38

สำหรับ ... ในลูป

สำหรับ ... ในห่วงปรับปรุงเมื่อจุดอ่อนของการห่วงโดยการกำจัดตรรกะนับและเงื่อนไขทางออก

ตัวอย่าง:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

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

แต่คุณยังต้องจัดการกับปัญหาของการใช้ดัชนีเพื่อเข้าถึงค่าของอาร์เรย์และนั่น stinks; มันเกือบทำให้สับสนมากกว่าเดิม

นอกจากนี้การ for ... in loop จะช่วยให้คุณประสบปัญหาใหญ่เมื่อคุณต้องการเพิ่มวิธีพิเศษให้กับอาร์เรย์ (หรือวัตถุอื่น) เนื่องจากสำหรับ ... ในลูปวนรอบคุณสมบัติที่นับได้ทั้งหมดซึ่งหมายความว่าถ้าคุณเพิ่มคุณสมบัติเพิ่มเติมใด ๆ ลงในต้นแบบของอาร์เรย์คุณสมบัติเหล่านั้นจะปรากฏในลูปด้วย

Array.prototype.decimalfy = function() {
  for (let i = 0; i < this.length; i++) {
    this[i] = this[i].toFixed(2);
  }
};

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

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

พิมพ์:

0

1

2

3

4

5

6

7

8

9

function () {สำหรับ (ให้ฉัน = 0; i <this.length; i ++) {this [i] = นี่ [i] .toFixed (2); }}

นี่คือเหตุผลที่ ... ในลูปจะหมดกำลังใจเมื่อวนลูปมากกว่าอาร์เรย์

หมายเหตุ : forEach loopเป็นอีกประเภทของ for loop ใน JavaScript อย่างไรก็ตามforEach()จริง ๆ แล้วเป็นวิธีอาร์เรย์ดังนั้นจึงสามารถใช้ได้เฉพาะกับอาร์เรย์เท่านั้น นอกจากนี้ยังไม่มีวิธีหยุดหรือทำลายลูป forEach หากคุณต้องการพฤติกรรมประเภทนั้นในการวนซ้ำคุณจะต้องใช้พื้นฐานสำหรับการวนซ้ำ

สำหรับ ... จากลูป

การfor ... of loop ถูกใช้เพื่อวนลูปข้อมูลประเภทใด ๆ ที่ iterable

ตัวอย่าง:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  console.log(digit);
}

พิมพ์:

0

1

2

3

4

5

6

7

8

9

สิ่งนี้ทำให้ for ... of loop เป็นรุ่นที่รัดกุมที่สุดของ for loops

แต่เดี๋ยวก่อนมีอีกมาก! สำหรับ ... ของลูปยังมีประโยชน์เพิ่มเติมบางอย่างที่แก้ไขจุดอ่อนของสำหรับและสำหรับ ... ในลูป

คุณสามารถหยุดหรือทำลาย ... สำหรับการวนซ้ำได้ตลอดเวลา

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  if (digit % 2 === 0) {
    continue;
  }
  console.log(digit);
}

พิมพ์:

1

3

5

7

9

และคุณไม่ต้องกังวลกับการเพิ่มคุณสมบัติใหม่ให้กับวัตถุ กระบวนการสำหรับ ... ของการวนซ้ำจะวนซ้ำค่าในวัตถุเท่านั้น


2
" สำหรับ ... ในลูปปรับปรุงตามจุดอ่อนของ for loop โดยกำจัดลอจิกการนับและเงื่อนไขการออก " - ไม่นั่นไม่ใช่สิ่งที่มันทำ ไม่ใช่เลย.
Bergi

1
@Bergi คุณช่วยอธิบายได้ไหมว่าทำไมคุณถึงคิดว่ามันไม่ใช่สิ่งที่ทำและสิ่งที่คุณคิดว่าดีขึ้นจริงหรือ
Elar

2
มันไม่ได้พัฒนาอะไรเลย แต่มี raison d'êtreเป็นของตัวเอง มันทำอะไรบางอย่างที่แตกต่างจากfor (var index=0; index<arr.length; index++)ลูป (โดยที่ตัวindexนับเป็นจำนวนเต็มไม่เหมือนในตัวอย่างของคุณ)
Bergi

ชนิดของทำให้มันสับสนว่าค่าอาร์เรย์ที่คุณเลือกสำหรับตัวอย่างสอดคล้องกับค่าดัชนีอาร์เรย์ ...
Sergey

20

ความแตกต่างfor..inและfor..of:

ทั้งสองfor..inและfor..ofกำลังวนลูปสร้างที่ใช้ในการทำซ้ำมากกว่าโครงสร้างข้อมูล ความแตกต่างเพียงอย่างเดียวคือสิ่งที่พวกเขาย้ำ:

  1. for..inวนซ้ำทุกคีย์คุณสมบัติที่นับได้ของวัตถุ
  2. for..ofวนซ้ำค่าของวัตถุที่ทำซ้ำได้ ตัวอย่างของวัตถุที่ทำซ้ำได้คืออาร์เรย์สตริงและ NodeLists

ตัวอย่าง:

let arr = ['el1', 'el2', 'el3'];

arr.addedProp = 'arrProp';

// elKey are the property keys
for (let elKey in arr) {
  console.log(elKey);
}

// elValue are the property values
for (let elValue of arr) {
  console.log(elValue)
}

ในตัวอย่างนี้เราสามารถสังเกตได้ว่าการfor..inวนซ้ำวนซ้ำเหนือปุ่มของวัตถุซึ่งเป็นวัตถุอาร์เรย์ในตัวอย่างนี้ คีย์เป็น 0, 1, 2 addedPropซึ่งสอดคล้องกับองค์ประกอบมากมายที่เราเพิ่มและ นี่คือarrลักษณะที่วัตถุอาร์เรย์ใน chrome devtools:

ป้อนคำอธิบายรูปภาพที่นี่

คุณเห็นว่าการfor..inวนซ้ำของเราไม่ได้ทำอะไรมากไปกว่าการวนซ้ำค่าเหล่านี้


การfor..ofวนซ้ำในตัวอย่างของเราวนซ้ำค่าของโครงสร้างข้อมูล 'el1', 'el2', 'el3'ค่าในตัวอย่างที่เฉพาะเจาะจงนี้ ค่าที่โครงสร้างข้อมูล iterable จะกลับมาใช้for..ofขึ้นอยู่กับชนิดของวัตถุ iterable ตัวอย่างเช่นอาร์เรย์จะส่งคืนค่าขององค์ประกอบอาร์เรย์ทั้งหมดในขณะที่สตริงส่งกลับอักขระทุกตัวของสตริง


8

for...inงบ iterates กว่าคุณสมบัติที่นับของวัตถุในการสั่งซื้อโดยพลการ คุณสมบัติที่นับได้คือคุณสมบัติเหล่านั้นที่มีการตั้งค่าสถานะภายใน [[นับจำนวน]] เป็นจริงดังนั้นหากมีคุณสมบัติที่นับได้ในห่วงโซ่ต้นแบบห่วงfor...inจะวนซ้ำในคุณสมบัติเหล่านั้นเช่นกัน

for...ofงบ iterates มากกว่าข้อมูลที่กำหนดวัตถุ iterable ที่จะซ้ำมากกว่า

ตัวอย่าง:

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];

for (let i in iterable) {
  console.log(i); // logs: 0, 1, 2, "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs: 0, 1, 2,
  }
}

for (let i of iterable) {
  console.log(i); // logs: 3, 5, 7
}

เหมือนก่อนหน้านี้คุณสามารถข้ามการเพิ่มhasOwnPropertyในfor...ofลูป


7

คำสั่งในการวนซ้ำคุณสมบัติที่นับได้ของวัตถุตามลำดับโดยพลการ

การวนซ้ำจะวนซ้ำไปตามคุณสมบัติที่นับได้ทั้งหมดของวัตถุเองและวัตถุนั้นสืบทอดจากต้นแบบของตัวสร้าง

คุณสามารถคิดว่ามันเป็น "สำหรับใน" โดยทั่วไป iterates และรายการคีย์ทั้งหมด

var str = 'abc';
var arrForOf = [];
var arrForIn = [];

for(value of str){
  arrForOf.push(value);
}

for(value in str){
  arrForIn.push(value);
}

console.log(arrForOf); 
// ["a", "b", "c"]
console.log(arrForIn); 
// ["0", "1", "2", "formatUnicorn", "truncate", "splitOnLast", "contains"]

for in จะแสดงเฉพาะคีย์หากมีการเพิ่มโดยเราจะไม่แสดงฟอร์แมทยูนิคอร์น
Milad

1
"formatUnicorn", "ตัด", "splitOnLast" "มี" String.prototypeพิมพ์ออกมาเพราะแทนที่
jasonxia23

6

มีชนิดข้อมูลที่กำหนดไว้แล้วบางประเภทซึ่งช่วยให้เราสามารถย้ำมันได้อย่างง่ายดายเช่น Array, Map, String Objects

ปกติสำหรับในการวนซ้ำมากกว่าตัววนซ้ำและการตอบสนองทำให้เรามีกุญแจที่อยู่ในลำดับของการแทรกดังแสดงในตัวอย่างด้านล่าง

  const numbers = [1,2,3,4,5];
   for(let number in number) {
     console.log(number);
   }

   // result: 0, 1, 2, 3, 4

ทีนี้ถ้าเราลองเหมือนกันกับการตอบสนองก็ให้ค่าที่ไม่ใช่กุญแจ เช่น

  const numbers = [1,2,3,4,5];
   for(let numbers of numbers) {
    console.log(number);
  }

  // result: 1, 2, 3, 4, 5

ดังนั้นเมื่อดูที่ตัววนซ้ำทั้งสองเราสามารถแยกความแตกต่างระหว่างพวกเขาทั้งสองได้อย่างง่ายดาย

หมายเหตุ: - สำหรับใช้งานได้เฉพาะกับ Symbol.iterator

ดังนั้นถ้าเราพยายามวนซ้ำวัตถุธรรมดามันจะทำให้เรามีข้อผิดพลาดเช่น -

const Room = {
   area: 1000,
   height: 7,
   floor: 2
 }

for(let prop in Room) {
 console.log(prop);
 } 

// Result area, height, floor

for(let prop of Room) {
  console.log(prop);
 } 

ห้องพักไม่สามารถรองรับได้

ตอนนี้สำหรับการวนซ้ำเราจำเป็นต้องกำหนด ES6 Symbol.iterator เช่น

  const Room= {
    area: 1000, height: 7, floor: 2,
   [Symbol.iterator]: function* (){
    yield this.area;
    yield this.height;
    yield this.floors;
  }
}


for(let prop of Room) {
  console.log(prop);
 } 

//Result 1000, 7, 2

นี่คือความแตกต่างระหว่างสำหรับในและสำหรับของ หวังว่ามันจะชัดเจนถึงความแตกต่าง


5

ข้อแตกต่างระหว่างลูปทั้งสองซึ่งไม่มีใครพูดถึงมาก่อน:

การทำลายfor...inนั้นเลิกใช้แล้ว ใช้for...ofแทน

แหล่ง

ดังนั้นถ้าเราต้องการใช้destructuringใน loop เพื่อรับทั้งindexและvalueของแต่ละองค์ประกอบarrayเราควรใช้for...ofloop กับmethod Arrayentries() :

for (const [idx, el] of arr.entries()) {
    console.log( idx + ': ' + el );
}

1
ใช่ @GalMargalit ฉันอ่านอย่างระมัดระวัง ฉันยอมรับว่าfor each...inไม่สนับสนุน (จุดแรก) แต่ฉันไม่ได้เขียนเกี่ยวกับเรื่องนี้ ... ฉันเขียนว่า "การทำลายล้างfor...inนั้นเลิกใช้แล้วใช้for...ofแทน" (จุดที่สอง): developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...... คุณเห็นด้วยกับฉัน @GalMargalit หรือไม่?
simhumileco

1
ฮ่าฮ่าคุณพูดถูกฉันไม่ได้อ่านอย่างระมัดระวัง! จริงฉันกำลังคิดอย่างเดียวกันและคิดว่าคุณหมายถึงคนอื่น
Gal Margalit

2

ทุกคนอธิบายว่าทำไมปัญหานี้จึงเกิดขึ้น แต่ก็ยังง่ายมากที่จะลืมมันแล้วเกาหัวของคุณว่าทำไมคุณถึงได้ผลลัพธ์ที่ผิด โดยเฉพาะอย่างยิ่งเมื่อคุณกำลังทำงานกับชุดข้อมูลขนาดใหญ่เมื่อผลลัพธ์ดูเหมือนดีเมื่อเห็นอย่างรวดเร็ว

การใช้ Object.entriesเพื่อให้มั่นใจว่าคุณจะได้ใช้งานคุณสมบัติทั้งหมด:

var arr = [3, 5, 7];
arr.foo = "hello";

for ( var [key, val] of Object.entries( arr ) ) {
   console.log( val );
}

/* Result:

3
5
7
hello

*/

2

เห็นคำตอบที่ดีมากมาย แต่ฉันตัดสินใจใส่ 5 เซนต์ของฉันเพื่อเป็นตัวอย่างที่ดี:

สำหรับในวง

วนซ้ำอุปกรณ์ประกอบฉากที่นับได้ทั้งหมด

let nodes = document.documentElement.childNodes;

for (var key in nodes) {
  console.log( key );
}

สำหรับวง

วนซ้ำทุกค่าที่ทำซ้ำได้

let nodes = document.documentElement.childNodes;

for (var node of nodes) {
  console.log( node.toString() );
}


2

ตอนที่ฉันเริ่มเรียนรู้เกี่ยวกับวงในและครั้งแรกฉันก็สับสนกับผลลัพธ์ของฉันเช่นกัน แต่ด้วยการวิจัยและความเข้าใจสองสามข้อคุณสามารถนึกถึงแต่ละวงดังต่อไปนี้:

  1. สำหรับ ... ใน ห่วงส่งกลับดัชนีของทรัพย์สินบุคคลและมีไม่มีผลกระทบของผลกระทบต่อมูลค่าทรัพย์สินก็ loops และผลตอบแทนที่ข้อมูลเกี่ยวกับคุณสมบัติและไม่คุ้มค่า เช่น

let profile = { name : "Naphtali", age : 24, favCar : "Mustang", favDrink : "Baileys" }

โค้ดด้านบนเป็นเพียงการสร้างวัตถุที่เรียกว่าโปรไฟล์เราจะใช้มันสำหรับทั้งสองตัวอย่างดังนั้นอย่าสับสนเมื่อคุณเห็นวัตถุโปรไฟล์ในตัวอย่างเพียงแค่รู้ว่ามันถูกสร้างขึ้น

ตอนนี้ให้เราใช้สำหรับ ... ในลูปด้านล่าง

for(let myIndex in profile){
    console.log(`The index of my object property is ${myIndex}`)
}
 // Outputs : 
        The index of my object property is 0
        The index of my object property is 1
        The index of my object property is 2
        The index of my object property is 3

ตอนนี้เหตุผลที่ผลลัพธ์เป็นเพราะเรามีคุณสมบัติสี่ (4)ในวัตถุโปรไฟล์และการจัดทำดัชนีตามที่เรารู้เริ่มต้นจาก0 ... nดังนั้นเราได้รับดัชนีคุณสมบัติ0,1,2,3เนื่องจากเราเป็น ทำงานกับfor..in loop

  1. สำหรับ ... ของวง *สามารถกลับทั้งสถานที่ให้บริการ , ค่า หรือ ทั้งสองให้มาดูที่วิธีการที่ ในจาวาสคริปต์เราไม่สามารถวนลูปผ่านวัตถุได้ตามปกติเช่นเดียวกับในอาร์เรย์ดังนั้นมีองค์ประกอบบางอย่างที่เราสามารถใช้เพื่อเข้าถึงตัวเลือกของเราจากวัตถุ

    • Object.keys ( object-name- go -here ) ส่งคืนคีย์หรือคุณสมบัติของวัตถุ

    • Object.values ( object-name- go -here ) >>> ส่งคืนค่าของวัตถุ

    • Object.entries ( วัตถุชื่อไป-ที่นี่ ) >>> ผลตอบแทนทั้งคีย์และค่าของวัตถุ

ด้านล่างเป็นตัวอย่างของการใช้งานให้ความสนใจกับ Object.entries () :

Step One: Convert the object to get either its key, value, or both.
Step Two: loop through.


// Getting the keys/property

   Step One: let myKeys = ***Object.keys(profile)***
   Step Two: for(let keys of myKeys){
             console.log(`The key of my object property is ${keys}`)
           }

// Getting the values of the property

    Step One: let myValues = ***Object.values(profile)***
    Step Two : for(let values of myValues){
                 console.log(`The value of my object property is ${values}`)
               }

เมื่อใช้Object.entries ()มีว่าคุณกำลังเรียกสองรายการบนวัตถุคือคีย์และค่า คุณสามารถโทรทั้งสองโดยรายการใดรายการหนึ่ง ตัวอย่างด้านล่าง

Step One: Convert the object to entries, using ***Object.entries(object-name)***
Step Two: **Destructure** the ***entries object which carries the keys and values*** 
like so **[keys, values]**, by so doing, you have access to either or both content.


    // Getting the keys/property

       Step One: let myKeysEntry = ***Object.entries(profile)***
       Step Two: for(let [keys, values] of myKeysEntry){
                 console.log(`The key of my object property is ${keys}`)
               }

    // Getting the values of the property

        Step One: let myValuesEntry = ***Object.entries(profile)***
        Step Two : for(let [keys, values] of myValuesEntry){
                     console.log(`The value of my object property is ${values}`)
                   }

    // Getting both keys and values

        Step One: let myBothEntry = ***Object.entries(profile)***
        Step Two : for(let [keys, values] of myBothEntry){
                     console.log(`The keys of my object is ${keys} and its value 
is ${values}`)
                   }

แสดงความคิดเห็นในส่วนที่ไม่ชัดเจน


1

for-inห่วง

for-inห่วงถูกนำมาใช้เพื่อการสำรวจผ่านคุณสมบัตินับของคอลเลกชันในการสั่งซื้อโดยพลการ คอลเลกชันเป็นวัตถุประเภทภาชนะที่มีรายการที่สามารถใช้ดัชนีหรือคีย์

var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];
var myString = "123";

console.log( myObject[ 'a' ], myArray[ 1 ], myString[ 2 ] );

for-inวนแยกคุณสมบัตินับจำนวน ( กุญแจ ) ของคอลเลกชันทั้งหมดในครั้งเดียวและวนซ้ำมันทีละครั้ง คุณสมบัติที่นับได้คือคุณสมบัติของคอลเลกชันที่สามารถปรากฏเป็นfor-inวง

ตามค่าเริ่มต้นคุณสมบัติทั้งหมดของ Array และ Object จะปรากฏเป็นfor-inลูป อย่างไรก็ตามเราสามารถใช้วิธีObject.definePropertyเพื่อกำหนดค่าคุณสมบัติของคอลเลกชันด้วยตนเอง

var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];

Object.defineProperty( myObject, 'd', { value: 4, enumerable: false } );
Object.defineProperty( myArray, 3, { value: 4, enumerable: false } );

for( var i in myObject ){ console.log( 'myObject:i =>', i ); }
for( var i in myArray ){ console.log( 'myArray:i  =>', i ); }

ในตัวอย่างด้านบนคุณสมบัติdของmyObjectและดัชนี3ของmyArrayไม่ปรากฏในfor-inลูปเนื่องจากถูกกำหนดค่าด้วยenumerable: falseห่วงเพราะพวกเขามีการกำหนดค่าด้วย

มีปัญหาเล็กน้อยเกี่ยวกับfor-inลูป ในกรณีของอาร์เรย์ที่for-inห่วงนอกจากนี้ยังจะพิจารณาmethodsเพิ่มในอาร์เรย์โดยใช้myArray.someMethod = fไวยากรณ์ แต่ซากmyArray.length4

for-ofห่วง

มันเป็นความเข้าใจผิดที่for-ofวนซ้ำมากกว่าค่าของคอลเลกชัน for-ofวนซ้ำวนซ้ำIterableวัตถุ iterable เป็นวัตถุที่มีวิธีการที่มีชื่อSymbol.iteratorโดยตรงหนึ่งในหนึ่งในต้นแบบของมัน

Symbol.iteratorวิธีควรกลับIterator ตัววนซ้ำเป็นวัตถุที่มีnextเมธอด วิธีการนี้เมื่อเรียกว่าผลตอบแทนvalueและdoneคุณสมบัติ

เมื่อเราย้ำiterableวัตถุโดยใช้for-ofห่วงที่Symbol.iteratorวิธีการที่จะถูกเรียกว่าครั้งหนึ่งเคยได้รับการiteratorวัตถุ สำหรับการทำซ้ำของทุกfor-ofห่วงnextวิธีการของวัตถุ iterator นี้จะถูกเรียกว่าจนกว่าจะdoneส่งกลับโดยnext()ผลตอบแทนที่โทรเท็จ ค่าที่ได้รับจากการfor-ofวนซ้ำสำหรับการวนซ้ำทุกครั้งหากvalueคุณสมบัติส่งคืนโดยการnext()เรียก

var myObject = { a: 1, b: 2, c: 3, d: 4 };

// make `myObject` iterable by adding `Symbol.iterator` function directlty on it
myObject[ Symbol.iterator ] = function(){
  console.log( `LOG: called 'Symbol.iterator' method` );
  var _myObject = this; // `this` points to `myObject`
  
  // return an iterator object
  return {
    keys: Object.keys( _myObject ), 
    current: 0,
    next: function() {
      console.log( `LOG: called 'next' method: index ${ this.current }` );
      
      if( this.current === this.keys.length ){
        return { done: true, value: null }; // Here, `value` is ignored by `for-of` loop
      } else {
        return { done: false, value: _myObject[ this.keys[ this.current++ ] ] };
      }
    }
  };
}

// use `for-of` loop on `myObject` iterable
for( let value of myObject ) {
  console.log( 'myObject: value => ', value );
}

for-ofวงใหม่ใน ES6 และเพื่อให้มีIterableและIterables ArrayประเภทคอนสตรัคมีSymbol.iteratorวิธีการในต้นแบบของมัน Objectคอนสตรัคเศร้าไม่ได้มี แต่Object.keys(), Object.values()และObject.entries()วิธีการกลับ iterable ( คุณสามารถใช้console.dir(obj)เพื่อตรวจสอบวิธีการต้นแบบ ) ประโยชน์ของการfor-ofวนรอบคือวัตถุใด ๆ ที่สามารถทำให้ iterable ได้แม้แต่ในแบบกำหนดเองDogและAnimalคลาสของคุณ

วิธีที่ง่ายที่สุดในการทำให้วัตถุทำซ้ำได้คือการใช้ตัวสร้างES6แทนการใช้ตัววนซ้ำแบบกำหนดเอง

ซึ่งแตกต่างจากfor-in, for-ofห่วงสามารถรอให้งาน async จะแล้วเสร็จในแต่ละซ้ำ นี่คือความสำเร็จโดยใช้awaitคำหลักหลังจากเอกสารforคำสั่งเอกสาร

ข้อดีอีกอย่างของfor-ofลูปคือมันรองรับ Unicode ตามข้อกำหนดของ ES6 สตริงจะถูกจัดเก็บด้วยการเข้ารหัส UTF-16 ดังนั้นตัวละครแต่ละตัวสามารถใช้อย่างใดอย่างหนึ่งหรือ16-bit 32-bitตามเนื้อผ้าสตริงจะถูกจัดเก็บด้วยการเข้ารหัส UCS-2 ซึ่งรองรับอักขระที่สามารถจัดเก็บได้ภายใน16 bitsเท่านั้น

ดังนั้นString.lengthจะส่งคืนจำนวน16-bitบล็อกในสตริง ตัวละครสมัยใหม่เช่นตัวอักษร Emoji ใช้เวลา 32 บิต ดังนั้นตัวละครตัวนี้จะกลับมาlength2. for-initerates ห่วงมากกว่าบล็อกและผลตอบแทนที่ไม่ถูกต้อง16-bit indexอย่างไรก็ตามfor-ofวนซ้ำตัวละครแต่ละตัวขึ้นอยู่กับข้อกำหนดของ UTF-16

var emoji = "😊🤣";

console.log( 'emoji.length', emoji.length );

for( var index in emoji ){ console.log( 'for-in: emoji.character', emoji[index] ); }
for( var character of emoji ){ console.log( 'for-of: emoji.character', character ); }


0

ฉันพบคำอธิบายต่อไปนี้จากhttps://javascript.info/arrayมีประโยชน์มาก:

วิธีที่เก่าแก่ที่สุดวิธีหนึ่งในการวนรอบรายการอาร์เรย์คือ for for loop over index:

let arr = ["Apple", "Orange", "Pear"];

for (let i = 0; i < arr.length; i++) { alert( arr[i] ); } But for arrays there is another form of loop, for..of:

let fruits = ["Apple", "Orange", "Plum"];

// iterates over array elements for (let fruit of fruits) { alert( fruit ); } The for..of doesn’t give access to the number of the current element, just its value, but in most cases that’s enough. And it’s shorter.

ในทางเทคนิคเนื่องจากอาร์เรย์เป็นวัตถุจึงเป็นไปได้ที่จะใช้สำหรับ .. ใน:

let arr = ["Apple", "Orange", "Pear"];

for (let key in arr) { alert( arr[key] ); // Apple, Orange, Pear } But that’s actually a bad idea. There are potential problems with it:

วนรอบสำหรับ .. ในซ้ำทุกคุณสมบัติไม่เพียง แต่ตัวเลข

มีสิ่งที่เรียกว่า "เหมือนอาร์เรย์" วัตถุในเบราว์เซอร์และในสภาพแวดล้อมอื่น ๆ ที่ดูเหมือนว่าอาร์เรย์ นั่นคือพวกเขามีคุณสมบัติความยาวและดัชนี แต่ก็อาจมีคุณสมบัติและวิธีการอื่น ๆ ที่ไม่ใช่ตัวเลขซึ่งเรามักไม่ต้องการ for..in loop จะแสดงรายการเหล่านั้น ดังนั้นหากเราต้องการทำงานกับวัตถุที่มีลักษณะคล้ายอาร์เรย์ดังนั้นคุณสมบัติ“ พิเศษ” เหล่านี้อาจกลายเป็นปัญหาได้

for..in loop ถูกปรับให้เหมาะสมสำหรับวัตถุทั่วไปไม่ใช่อาร์เรย์และทำให้ช้าลง 10-100 เท่า แน่นอนมันยังเร็วมาก การเร่งความเร็วอาจสำคัญในคอขวดเท่านั้น แต่ถึงอย่างนั้นเราก็ควรตระหนักถึงความแตกต่าง

โดยทั่วไปเราไม่ควรใช้สำหรับในอาร์เรย์


0

นี่เป็นตัวช่วยจำที่มีประโยชน์สำหรับการจดจำความแตกต่างระหว่างfor...inLoop และfor...ofLoop

"ดัชนีในวัตถุของ"

for...in Loop=> วนซ้ำดัชนีในอาร์เรย์

for...of Loop=> วนซ้ำวัตถุของวัตถุ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.