您的位置:首页 > 其它

underscore源码阅读整理

2016-04-26 15:36 211 查看
underscore是我阅读的第一份源码,这份代码比较小巧,只有1500行,我阅读的版本是1.8.3.underscore里封装了很多功能性的函数,和jQuery不同,我觉得jQuery的特点是对针对DOM,而underscore里都是基于JS的功能性函数,比如each,map等等。

以下内容仅是我阅读过程中记录的笔记,可能会有错误或理解不到位的地方。。。

整体结构

underscore中:

(function(){
var root = this;
var previousUnderscore = root._;
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
this._wrapped = obj;
};
}).call(this);


最外层是个立即执行函数,用call函数把this传进去,我认为因为underscore既可以运行在浏览器端又可以运行在服务器端,所以它传入的是this,而不是像jQuery一样直接传进去window

这里有几个比较重要的地方:

像jQuery注册在$上一样,underscore注册在’‘上,而且为了避免冲突都会先保存一下之前的root.

‘_’其实是一个函数,如果传入的是’_’的实例则直接返回,如果不是则new一个出来,并把它放到_wrapped属性中。举个例子:

_([1,2,3]) ==》 Object{_wrapped:[1,2,3], _proto_:Object} //其中_proto_上有所有的方法


jQuery中:

(function(window, undefined) {

})(window);


jQuery中是直接指定了this=window

几个重要的公共方法

var optimizeCb = function(func, context, argCount) {
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);};
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, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};

var cb = function(value, context, argCount) {
if (value == null) return _.identity;
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
if (_.isObject(value)) return _.matcher(value);
return _.property(value);
};


optimizeCb函数的传入参数只能是function,根据传入的参数不同返回不同的合理的回调函数

cb函数一般用来处理作为迭代器的函数,传入的value可以是函数、object或者property,但是返回的一定会是函数

var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
if (length < 2 || obj == null) return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index],
keys = keysFunc(source),
l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
}
}
return obj;
};
};


_.extend和 _.extendAll其实就是调用这个函数实现的,所以他的功能就是扩展object

这里传入的参数keysFunc是用来取用于扩展的keys,因为传入的是_.keys和 _.allKeys两种决定了是否可以拿到!hasOwnProperty的属性

这里undefinedOnly的作用我也不太理解,源码中调用这个函数的时候从来没有传入过undefinedOnly这个参数。。。。

var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
if (nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
};


用于继承的函数,其实就是ES5的Object.create
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: