找回密码
 立即注册
首页 业界区 业界 Web前端入门第 62 问:JavaScript 循环结构注意事项 ...

Web前端入门第 62 问:JavaScript 循环结构注意事项

卢铃语 4 天前
HELLO,这里是大熊的前端开发笔记。
循环作为 算法与数据结构 中的基石,JS 与其他编程语言一样,都提供了多种循环结构用于处理数据。
for 循环

事物的开端往往都是从最常用的开始,循环结构咱们从 for 循环说起。
语法:
  1. for (初始化; 条件; 增量) {
  2.   // ...
  3. }
复制代码
示例:
  1. // 增量每次 +1
  2. for (let i = 0; i < 10; i++) {
  3.   console.log(i);
  4. }
  5. // 增量每次 +2
  6. for (let i = 0; i < 10; i += 2) {
  7.   console.log(i);
  8. }
复制代码
性能优化:
在使用 for 循环遍历数组的时候,可以提前缓存数组长度,减少 length 的访问次数。
  1. const arr = ['前', '端', '路', '引'];
  2. // 提前使用 len 缓存数组长度
  3. for (let i = 0, len = arr.length; i < len; i++) {
  4.   console.log(arr[i]);
  5. }
复制代码
此示例中使用了 let 同时声明了多个变量,在常规的代码编写中,不建议这么使用,但在循环体这种特殊情况下,这么写也能接受。
  1. // 同时声明多个变量
  2. let a = '前端路引', b = 2, c = true;
复制代码
增量不一定要使用 i++ 自增,也可以使用 i-- 递减,或者使用 i += 2 步进,甚至可以是 i += 10。
for in 循环

ES6 规范出现之前,只能使用 for in 循环遍历对象,但这哥们有个坑,不止会遍历对象自身属性,还能遍历原型链上可枚举属性。
  1. const obj1 = {
  2.   name: '前端路引',
  3.   age: 1,
  4.   'favorite-color': 'red',
  5. }
  6. for (let key in obj1) {
  7.   console.log(key, obj1[key]);
  8. }
  9. /*
  10. // 输出结果
  11. name 前端路引
  12. age 1
  13. favorite-color red
  14. */
复制代码
看个遍历原型链例子:
  1. // 如果有兄弟不小心给对象的原型链上填了一笔
  2. Object.prototype.test = '我是原型链上的测试属性';
  3. const obj1 = {
  4.   name: '前端路引',
  5.   age: 1,
  6.   'favorite-color': 'red',
  7. }
  8. for (let key in obj1) {
  9.   console.log(key, obj1[key]);
  10. }
  11. /*
  12. // 输出结果
  13. name 前端路引
  14. age 1
  15. favorite-color red
  16. test 我是原型链上的测试属性
  17. */
  18. for (const key in obj1) {
  19.   if (obj.hasOwnProperty(key)) {  // 过滤掉原型链属性
  20.     console.log(key, obj1[key]);
  21.   }
  22. }
  23. /*
  24. // 输出结果
  25. name 前端路引
  26. age 1
  27. favorite-color red
  28. */
复制代码
如上所示,代码编写规范建议不要对 JS 自身的原型链做修改,扩展原型链虽然方便了一些对象操作,但实际上这是埋了雷的,不知道啥时候就会引爆!!
在使用 for in 循环也需要注意原型链的属性,必须使用 hasOwnProperty 方法来过滤掉原型链上的属性。
for of 循环

由于 for in 的各种弊端,后来定规范的大佬们,就新增了一个 for of 循环用于遍历可迭代对象,比如:数组、字符串、Set、Map 等等。
  1. const obj1 = {
  2.   name: '前端路引',
  3.   age: 1,
  4.   'favorite-color': 'red',
  5. }
  6. // for of 循环
  7. for (let [key, value] of Object.entries(obj1)) {
  8.   console.log(key, value);
  9. }
  10. /* // 以上 let [key, value] 使用了 解构赋值,其代码等于
  11. for (let item of Object.entries(obj1)) {
  12.   const [key, value] = item;
  13.   console.log(key, value);
  14. }
  15. // 又等于
  16. for (let item of Object.entries(obj1)) {
  17.   const key = item[0];
  18.   const value = item[1];
  19.   console.log(key, value);
  20. }
  21. */
复制代码
for of 无法直接遍历对象,需要遍历对象时,需使用内置方法 Object.entries 将对象转为数组,再使用 for of 遍历,或者使用 Object.keys/Object.values 将对象转为键/值数组再遍历。
相比于 for in 循环,for of 循环性能更好,也不用考虑原型链问题。
while 循环

while 循环多用于不确定循环次数的应用场景,比如读取文件数据流,并不知道需要循环多少次才能读取完。
  1. let i = 0;
  2. while (i < 3) {
  3.   console.log(i);
  4.   i++;
  5. }
复制代码
一般能用 for 循环的场景,都能使用 while 循环替代。
do while 循环

这个循环可有意思了,不管条件是否满足,都会先跑一次循环体,再判断条件。
应用场景例子:必须让用户先输入,再判断条件,直到输入正确才继续。
[code]let userInput;do {  userInput = prompt("请输入一个大于 10 的数字:");} while (isNaN(userInput) || Number(userInput)
您需要登录后才可以回帖 登录 | 立即注册