Underscore源码(1)

每次看源码都要感叹一句,哎,我头疼的英语呀!!!

(function() {

// this === window
var root = this;

// 全局变量 previousUnderscore保存_的值,主要是为了防止_被占用,可以使用_.noConflict()恢复
var previousUnderscore = root._;

// 用变量保存数组,对象,函数,的原型
// 这个是为了以后压缩出更小的体积,Array.prototype 是不能压缩的,否则js解析器就不认识了,ArrayProto却可以直接压缩成变量o
var ArrayProto = Array.prototype,
    ObjProto = Object.prototype,
    FuncProto = Function.prototype;

// 保存一些原型方法,压缩了,还有后面使用也方便,很多地方都判断如果具有原型方法,就使用原型方法,否则使用补丁方法
var
    push             = ArrayProto.push,
    slice            = ArrayProto.slice,
    toString         = ObjProto.toString,
    hasOwnProperty   = ObjProto.hasOwnProperty;

var
    nativeIsArray      = Array.isArray,
    nativeKeys         = Object.keys,
    nativeBind         = FuncProto.bind,
    nativeCreate       = Object.create;

// 这是一个原型引用的裸对象,后面会用到
var Ctor = function(){};

// 就是添加_wrapped = obj,类似于迭代。
var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);
    this._wrapped = obj;
};

// 这里是兼容node的模块,以及打包时的变量引用
if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
        exports = module.exports = _;
    }
    exports._ = _;
} else {
    root._ = _;
}

// 版本
_.VERSION = '1.8.2';

// Internal:内部
// efficient:有效率的
// current:现在的
// engines:发动机
// (for current engines):对于目前的引擎
// repeatedly:反复地
// 返回一个有效的(当前引擎)版本的内部函数在回调中传递的,可复用于其他的'_'.
// 这个函数在内部用的特别多,好多地方都是用这里做迭代的
var optimizeCb = function(func, context, argCount) {
    // 如果 context = undefined 则返回函数本身
    if (context === void 0) return func;
    // 如果argCount不存在或者等于3
    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;
    // 如果是函数,则调用optimizeCb
    if (_.isFunction(value)) return optimizeCb(value, context, argCount);
    // 返回对象本身,matcher用来鉴别是否是对象
    if (_.isObject(value)) return _.matcher(value);
    // 添加值到property
    return _.property(value);
};
_.iteratee = function(value, context) {
    return cb(value, context, Infinity);
};

// 创建一个内部函数分配器功能。
var createAssigner = function(keysFunc, undefinedOnly) {
    return function(obj) {
        var length = arguments.length;
        // 如果参数不存在,并且找不到obj,则返回'_'
        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;
    };
};

// 创建一个从另一个继承的新对象的内部函数。
// result 继承了Ctor的原型 ,Ctor只是用来过度的,用后就被抛弃了
// 基本就是一个过渡函数
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;
};

// collection : 收集
// 一个内部函数,确保数组的length是有效的。
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
// 确定是一个列表,并且有length属性
var isArrayLike = function(collection) {
    var length = collection != null && collection.length;
    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
};

// 定义插件方法,
var result = function(instance, obj) {
    return instance._chain ? _(obj).chain() : obj;
};

_.mixin = function(obj) {
    _.each(_.functions(obj), function(name) {
        var func = _[name] = obj[name];
        _.prototype[name] = function() {
            var args = [this._wrapped];
            push.apply(args, arguments);
            return result(this, func.apply(_, args));
        };
    });
};

// 将_上的方法,全部添加到原型对象上
_.mixin(_);
// 兼容使用 AMD  的模块化方式
if (typeof define === 'function' && define.amd) {
    define('underscore', [], function() {
        return _;
    });
}
}.call(this));

你可能感兴趣的:(Underscore源码(1))