在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(),它会改变索引的值,从而判断有没有迭代到最后

运行结果:

 

posted on 2018-02-28 15:18  huanying2015  阅读(433)  评论(0编辑  收藏  举报