当前位置: 首页 > 工具软件 > Each > 使用案例 >

Layui源码解读之each函数(迭代器模式)

岳刚洁
2023-12-01

一、each函数 源码

    // 遍历 (内部迭代)
    Layui.prototype.each = function (obj, fn) {
        var key;
        var that = this; 
        var callFn = function (key, obj) { // 回调函数
            return fn.call(obj[key], key, obj[key]);
        };

        // fn 不为 function 类型, 返回that
        if(typeof fn !== 'function') return that;

        // 优先处理数组结构
        if(that._isArray(obj)){
            for(key = 0; key < obj.length; key++){

                // 返回 true 时, 不执行
                if(callFn(key, obj)) break;
            }
        } else {
            for(key in obj){
                if(callFn(key, obj)) break;
            }
        }
        return that;
    };

可以看出each函数源码,还是非常简单的。总的运行如下图

不是
不是
不是
不是
不是
不是
开始
输入 obj, fn
初始化key和存储当前this
fn是否是函数类型
结束并返回that
是否是数组
key被obj中可遍历属性赋值
key=0
key 小于 obj.length?
执行回调函数,返回的结果是否为true?
key++
key在obj中是否存在?
执行回调函数,返回的结果是否为true?
obj下一个可以遍历的属性赋值给key

二、迭代器模式

迭代器模式概述: 迭代器模式是提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内容表示.迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素.

迭代器一般分为两种: 内部迭代器和外部迭代器.layui.each函数是内部迭代器.
这里主要通过完整一个layui的each内部迭代器来展示如何书写迭代器,对于外部迭代器有兴趣的可以自行补充.

一个简单的内部迭代器

        let each =function(ary, callback){
            for(var i = 0, l = ary.length; i<l; i++){
                callback.call(ary[i], i ,ary[i]); // this 显示绑定
            }
        }

        each(['kh1', 'kh2', 'kh3'], function(index, item){
            console.log('kh', index, item);
        })

这里定义了一个简单的迭代数组的内部迭代器函数和layui中基本相似,与layui中不同之处在于layui中加入了迭代类数组对象和字面量对象功能和layui中特有判断.

可以看到each函数的内部已经定义好了迭代规则,它完全接手整个迭代过程,外部只需要一次初始调用.

完善内部迭代器

加入迭代类数组对象和字面量对象迭代

let each =function(obj, callback){
            var value;
            var i = 0;
            var length = obj.length;
            var isArray = Array.isArray(obj);

            if(isArray){
              for(; i < length; i++){
                value = callback.call(obj[i], i ,obj[i]);
                if(!value) break;
              }
            } else {
                for (i in obj){
                  value = callback.call(obj[i], i ,obj[i]);
                  if(!value) break;
                }
            }
        }

        each(['kh1', 'kh2', 'kh3'], function(index, item){
            console.log('kh', index, item);
        })

总结: 迭代器模式不是什么深奥的东西,jq, js等框架和语言中都内置了迭代器.除此之外不管是内部迭代器还是外部迭代器都有优缺点,应选择适合自己场景的迭代器.

更多源码请查看github

源码github

 类似资料: