Underscore骨骼

本文介绍了Underscore.js库的核心构造函数,包括遍历、类型检测、数组和对象操作方法的实现,以及链式操作的原理和使用示例。
摘要由CSDN通过智能技术生成

// Underscore骨骼  
(function () { var root \= this; var breaker \= {}; var ArrayProto \= Array.prototype, ObjProto \= Object.prototype; var nativeForEach \= ArrayProto.forEach,  
        nativeMap \= ArrayProto.map,  
        nativeFilter \= ArrayProto.filter,  
        nativeKeys \= Object.keys; var slice \= ArrayProto.slice,  
        unshift \= ArrayProto.unshift,  
        hasOwnProperty \= ObjProto.hasOwnProperty; // 构造函数  
 var \_ \= function (obj) { return new wrapper(obj); }; // 向全局暴露接口  
 root.\_ \= \_; // 类型检测  
 \_.isNumber \= function (obj) { return !!(obj \=== 0 || (obj && obj.toExponential && obj.toFixed));  
    };  
    \_.isFunction \= function (obj) { return !!(obj && obj.constructor && obj.call && obj.apply);  
    }; // 遍历扩展  
 var each \= \_.each \= \_.forEach \= function (obj, iterator, context) { if (obj \=== null) return; if (nativeForEach && obj.forEach \=== nativeForEach) {  
            obj.forEach(iterator, context);  
        } else if (\_.isNumber(obj.length)) { for (var i \= 0, l \= obj.length; i < l; i++) { if (iterator.call(context, obj\[i\], i, obj) \=== breaker) return;   
            }  
        } else { for (var key in obj) { if (hasOwnProperty.call(obj, key)) { if (iterator.call(context, obj\[key\], key, obj) \=== breaker) return;   
                }   
            }  
        }  
    }; // 返回对象上面的函数名  
 \_.functions \= \_.methods \= function (obj) { return \_.filter(\_.keys(obj), function (key) { return \_.isFunction(obj\[key\])}).sort();  
    }; // 过滤数组  
 \_.filter \= \_.select \= function (obj, iterator, context) { var results \= \[\]; if (obj \== null) return results; if (nativeFilter && obj.filter \=== nativeFilter) return obj.filter(iterator, context);  
          
        each(obj, function (value, index, list) { if (iterator.call(context, value, index, list)) results\[results.length\] \= value;   
        }); return results;  
    }; // 获取key值  
 \_.keys \= nativeKeys || function (obj) { if (obj !== Object(obj)) throw new TypeError('Invalid object'); var keys \= \[\]; for (var key in obj) if (hasOwnProperty.call(obj, key)) keys\[keys.length\] \= key; return keys;  
    }; // 用于实验的map方法  
 \_.map \= function (obj, iterator, context) { var results \= \[\]; if (obj \== null) return results; if (nativeMap && obj.map \=== nativeMap) return obj.map(iterator, context);  
        each(obj, function (value, index, list) {  
            results\[results.length\] \= iterator.call(context, value, index, list);  
        }); return results;  
    }; // 链式操作主要部分  
 var wrapper \= function (obj) { this.\_wrapped \= obj; };  
  
    \_.prototype \= wrapper.prototype; // 扩展自定义方法到Wrap包装器上  
 \_.mixin \= function (obj) {  
        each(\_.functions(obj), function (name) {  
            addToWrapper(name, \_\[name\] \= obj\[name\]);  
        });  
    }; // 是否对结果进行链式包装返回  
 var result \= function (obj, chain) { return chain ? \_(obj).chain() : obj;  
    }; // 将方法扩展到包装器的原型上  
 var addToWrapper \= function (name, func) {  
        wrapper.prototype\[name\] \= function () { var args \= slice.call(arguments);  
            unshift.call(args, this.\_wrapped); return result(func.apply(\_, args), this.\_chain);  
        };  
    }; // 将所有Underscore上的方法添加到Wrap包装器上  
 \_.mixin(\_); // 扩展Array上的方法到wrap包装器上-包装原数组  
 each(\['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'\], function (name) { var method \= ArrayProto\[name\];  
        wrapper.prototype\[name\] \= function () {  
            method.apply(this.\_wrapped, arguments); return result(this.\_wrapped, this.\_chain);  
        };  
    }); // 扩展Array上的方法到wrap包装器上-包装返回值  
 each(\['concat', 'join', 'slice'\], function (name) { var method \= ArrayProto\[name\];  
        wrapper.prototype\[name\] \= function () { return result(method.apply(this.\_wrapped, arguments), this.\_chain);  
        };  
    }); // 添加链式方法的实现  
 wrapper.prototype.chain \= function () { this.\_chain \= true; return this;  
    }; // 提取链式包装的内容  
 wrapper.prototype.value \= function () { return this.\_wrapped;  
    };  
  
})();  
  
// 结果测试 步骤:将数组\[1,2,3\]进行链式包装,然后将其用val \* 2来map,紧接着用filter进行val < 5过滤,   
// 然后pop,concat最后获取其值value  
var re \= \_(\[1,2,3\]).chain().map(function (val) { return val \* 2;  
}).filter(function (val) { return val < 5;  
}).pop().concat(\['5'\]).value();  
  
alert(re);  

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昔人'

你的鼓励将是我创造的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值