常规遍历

准备数据

let arr = [
  {
    name: 'Lance',
    age: 27
  },
  {
    name: 'GC',
    age: 30
  },
  {
    name: 'Jerry',
    age: 28
  }
]
// 给 arr 原型上加属性
arr.__proto__["12"] = {
  name: 'Sherry',
  age: 25
}
arr.__proto__["13"] = {
  name: 'Summer',
  age: 27
}
Object.defineProperty(arr.__proto__, '14', {
  value: {
    name: 'Elephant',
    age: 34
  },
  enumerable: true, // 使其可枚举
})

标准 for 循环

for (let i = 0; i < arr.length; i++) {
  let item = arr[i];
  if (item.name === 'GC') break;
  console.log(item);
}
// 打印完 { name: 'Lance', age: 27 } 就退出

for-in 遍历对象

for (const key in arr) {
  let item = arr[key];
  if (item.name === 'Elephant') break;
  console.log(item);
}

// 顺序:1. 自身属性(1.1 整数属性 1.2 其他按创建顺序) 2. 原型链属性(小步骤同自身属性)
// { name: 'Lance', age: 27 }
// { name: 'GC', age: 30 }
// { name: 'Jerry', age: 28 }
// { name: 'Sherry', age: 25 }
// { name: 'Summer', age: 27 }
var obj = {
  name: 'Lance',
  "1": "1",
  "2": "2",
  age: 27
}
obj.__proto__.aa = "aa";
obj.__proto__["22"] = "22";
obj.__proto__["11"] = "11";

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

// 打印
// 1 1
// 2 2
// name Lance
// age 27
// 11 11
// 22 22
// aa aa

🌈 forEach

// 跳出本次循环
arr.forEach((cur, idx, arr) => {
  if (cur.name === 'GC') return;
  console.log(cur);
});
// 打印
// { name: 'Lance', age: 27 }
// { name: 'Jerry', age: 28 }

// try-catch + throw Error 退出循环
try {
  arr.forEach((cur, idx, arr) => {
    if (cur.name === 'GC') throw new Error('退出循环');
    console.log(cur);
  });
} catch (err) {
  console.log(err);
}
// 打印
// { name: 'Lance', age: 27 }
// Error: 退出循环

// 总是返回 undefined
const ret = arr.forEach((cur, idx, arr) => {
  if (cur.name === 'GC') return '123';
  console.log(cur);
  return '321';
});
console.log(ret); // undefined

for-of 遍历可迭代对象

for (const value of arr) {
  if (value.name === 'GC') break;
  console.log(value);
}
// { name: 'Lance', age: 27 }