在js 中,有一些方法, 可以很方便的遍历出数据,不用进行for循环就可以,是怎么实现的呢?
例如:在javascript 中的forEach 方法:打印一个数组的索引和项目:
1. forEach 函数循环
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <script> 9 [10, 20, 30, 40, 50, 80, 33].forEach((val, key, curarr) => { 10 console.log("数组的第" + key + "项是:" + val); 11 }); 12 </script> 13 </head> 14 <body> 15 </body> 16 </html>
运行结果:
这里相当于一个for 循环,只是不需要进行for循环的判断,而是直接输出的
2. 自己封装一个循环函数,在jquery中也有一个each 函数,这里为了区分定义名字为 each1 函数,要求:循环出每一项,并且输出索引和当前项目,如下:
1 <script> 2 var each1 = function(obj, fn) { 3 for (var i = 0, len = obj.length; i < len; i++) { 4 // call函数的作用:在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。 5 // 此处 call 函数的作用,改变函数的this指向,把this指向obj,然后把(i,obj[i])作为函数参数,调用fn 函数 6 fn.call(obj, i, obj[i]); 7 } 8 }; 9 each1([101, 20, 30], function(key, val) { 10 // 因为each1 函数中,使用call 改变了函数指向,所以此处this 指向数组[101,20,30] 11 console.log(this); 12 // 此处为fn 函数内部,所以key,和val 来自fn 的参数;而fn的参数来自于 fn.call(obj,i,obj[i]),是由each1 函数内部的for循环得来的 13 console.log("当前项目的索引为:" + key + ",项目值为" + val); 14 }); 15 </script>
运行结果:
3. 自己封装一个each 方法:封装成组件调用each 方法:
1 <script> 2 ; 3 (function(window, undefined) { 4 var $ = function(arr) { 5 this.elements = arr; 6 } 7 $.prototype.each = function(fn) { 8 for (var i = 0, len = this.elements.length; i < len; i++) { 9 fn.call(this.elements, i, this.elements[i]) 10 } 11 }; 12 window.$ = $; 13 })(window, undefined); 14 15 var obj = new $([10, 20, 30, 40, 50]); 16 obj.each(function(index, val) { 17 console.log(this); 18 console.log("当前数组项目的索引是:" + index + ",数组的值为:" + val); 19 }); 20 </script>
运行结果:
4. 迭代器:制作一个迭代器
1 <script> 2 var Iterator = function(obj) { 3 var curInd = 0; // 当前索引,初始索引设定为0 4 // 获取对象的当前项目的下一项的索引 5 var next = function() { 6 curInd++; 7 }; 8 // 判定是否循环到了最后一项;当循环到最后一项时,索引等于obj.length;此处返回的是一个布尔值 9 // 因为执行next函数,每执行一次,curInd 就加1,所以当curInd 等于obj.length-1时,说明到了最后一项, 10 // 所以当isDone返回的结果是true时,说明curInd的值已经大于obj.length了 11 var isDone = function() { 12 return curInd >= obj.length; 13 }; 14 // 返回当前项目的值,通过当前索引获取 15 var current = function() { 16 return obj[curInd]; 17 }; 18 // 这里返回一个对象, 对象里包括三个函数, next, isDone, current 19 return { 20 next: next, 21 isDone: isDone, 22 current: current 23 }; 24 } 25 26 var it1 = Iterator([10, 20, 30, 40, 50, 60]); 27 while (!it1.isDone()) { //只要迭代器 没有到末尾, 我就开始是迭代 28 console.log(it1.isDone(), it1.current()); 29 it1.next(); 30 } 31 </script>
迭代器有没有到最后,使用在while的执行体有这个函数:it1.next(),它会改变索引的值,从而判断有没有迭代到最后
运行结果: