UnderScore源码解析

博主每天都会更一个方法,希望大家共同进步

一.Array中的方法:

  1. each方法:与Array.prototype.forEach用法相同,但是each可用于对象、类数组、字符串

遍历 list 中的所有元素,按顺序用每个元素当做参数调用 iteratee 函数。如果传递了 context 参数,则把 iteratee 绑定到 context 对象上。每次调用 iteratee 都会传递三个参数:(element, index, list)。如果 list 是个 JavaScript 对象, iteratee 的参数是 (value, key, list))。返回 list 以方便链式调用。
             //声明一个全局对象,以后所有的方法都会挂载到该全局对象上
            var _ = {};
            
            //optimizeCb方法主要用于为迭代函数指定this
            //这个不需要现在就理解
            var optimizeCb = function(func, context, argCount) {
                //如果没有指定this,就把迭代函数直接返回
                if(context == void 0) {
                    return func;
                };
                switch(argCount == null ? 3 : argCount) {
                    case 1:return function(value) {
                        return func.call(context, value);
                    };
                    case 2:return function(value, other) {
                        return func.call(context, value, other);
                    };
                    //主要是_.each _.map等方法
                    case 3:return function(value, index, collection) {
                        return func.call(context, value, index, collection);
                    };
                    case 4:return function(accumulator, value, index, collection) {
                        return func.call(context, accumulate, value, index, collection);
                    }
                }
            }
            
            var property = function(key) {
                return function(obj) { //判断是否传递了形参
                    //典型闭包,内部函数保留了外部函数的作用域链接
                    //ES3中,外部函数的VO对象不会销毁
                    //ES6中,外部函数的词法环境不会销毁
                    return obj == null ? void 0 : obj[key];
                }
            }
            //JavaScript最大精确整数
            var MAX_INDEX = Math.pow(2, 53) - 1;
            //getLength是一个获取length的函数
            var getLength = property('length');
            
            //什么是类数组:有length属性,且length属性为正整数    
            //不要传递类似{length: 10}这样的对象
            var isArrayLike = function(obj) {
                var length = getLength(obj);
                //如果length属性为Number型,且length为正整数,就返回true
                return typeof length ==='number' && length >=0 && length < MAX_INDEX; 
            }

            //_.each:数组的每个元素都会作为参数调用一次迭代函数,obj可以是类数组和对象
            //_.each:不要传递类似{length: 10}这样的对象
            //_.each(list, iteratee, [context])
            //第一个参数为类数组或对象或字符串
            //第二个参数为迭代方法,可通过context来指定该迭代方法的this
            //第三个参数是可选的,用于指定迭代函数的this
            _.each = function(obj, iteratee, context) { //声明一个函数表达式
                let i, length;
                //查看是否传递了this
                iteratee = optimizeCb(iteratee, context);
                if(isArrayLike(obj)) { //如果是类数组
                    for(i = 0, length = obj.length; i < length; i++) {
                        iteratee(obj[i], i, obj);
                    }
                } else{
                    //如果是对象
                    let keys = _.keys(obj);
                    for(i = 0, length = keys.length; i < length; i++) {
                        var currentKey = keys[i];
                        iteratee(obj[currentKey], i, obj);
                    }    
                }
                return obj; //供链式调用,即_.each().其它方法
            }
            //用于将对象的key抽取出来,组成一个数组 
            _.keys = function(obj) {
                //返回对象的keys数组
                return Object.keys(obj);
            }
            //_.each方法和Array.prototype.forEach方法类似
            var arr = [1, 2, 3];
            _.each("abcd", function(item, index, obj) {
                console.log(item, index, obj);
                console.log(this);//Number{10}
            }, 10)
                                                        
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值