美文网首页
Underscore源码(1)

Underscore源码(1)

作者: ____雨歇微凉 | 来源:发表于2016-11-21 18:32 被阅读25次

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

    (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)

          本文链接:https://www.haomeiwen.com/subject/ikiupttx.html