underscore 0.1.0バージョンのソース読み取り


前言
この文章は後のunderscoreの現バージョンのソースコードのために敷き詰めて、まず最初のバージョンを感じます
  • 0.1.0バージョンで十分小さい
  • このバージョンはもう10年近くの歴史があります
  • はいいところがあります.

  • 0.1.0バージョンのソース分析
    // Underscore.js
    // (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
    // Underscore is freely distributable under the terms of the MIT license.
    // Portions of Underscore are inspired by or borrowed from Prototype.js, 
    // Oliver Steele's Functional, And John Resig's Micro-Templating.
    // For all details and documentation:
    // http://documentcloud.github.com/underscore/
    window._ = {
      
      VERSION : '0.1.0',
      
      /*------------------------ Collection Functions: ---------------------------*/
      //     
      // The cornerstone, an each implementation.
      // Handles objects implementing forEach, each, arrays, and raw objects.
    
      each : function(obj, iterator, context) {
        var index = 0;
        try {
          if (obj.forEach) {
            //  forEach    forEach
            obj.forEach(iterator, context);
          } else if (obj.length) {
            //           
            for (var i=0; i= result.computed) result = {value : value, computed : computed};
          //            computed       
        });
        return result.value;
      },
      
      // Return the minimum element (or element-based computation).
      min : function(obj, iterator, context) {
        if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
        var result;
        _.each(obj, function(value, index) {
          var computed = iterator ? iterator.call(context, value, index) : value;
          if (result == null || computed < result.computed) result = {value : value, computed : computed};
        });
        return result.value;
      },
      
      // Sort the object's values by a criteria produced by an iterator.
      sortBy : function(obj, iterator, context) {
        //             
        //                  
        // map    ,        。          
        //         criteria          (        )
        return _.pluck(_.map(obj, function(value, index) {
          return {
            value : value,
            criteria : iterator.call(context, value, index)
          };
        }).sort(function(left, right) {
          var a = left.criteria, b = right.criteria;
          //         
          return a < b ? -1 : a > b ? 1 : 0;
        }), 'value');
        //      pluck     map       
      },
      
      // Use a comparator function to figure out at what index an object should
      // be inserted so as to maintain order. Uses binary search.
      //          
      //                     
      sortedIndex : function(array, obj, iterator) {
        iterator = iterator || function(val) { return val; };
        //         
        var low = 0, high = array.length;//      length
        //       
        // 
        while (low < high) {
          var mid = (low + high) >> 1;
          //      (important    )
          iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
        }
        return low;
      },
      
      // Convert anything iterable into a real, live array.
      //     (        )
      toArray : function(iterable) {
        if (!iterable) return []; //       []
        if (_.isArray(iterable)) return iterable; //       
        return _.map(iterable, function(val){ return val; });//       ,  map    
      },
      
      // Return the number of elements in an object.
      //          
      size : function(obj) {
        return _.toArray(obj).length;
      },
      
      /*-------------------------- Array Functions: ------------------------------*/
      
      // Get the first element of an array.
      //          
      first : function(array) {
        return array[0];
      },
      
      // Get the last element of an array.
      //           
      last : function(array) {
        return array[array.length - 1];
      },
      
      // Trim out all falsy values from an array.
      //         
      //           false          
      compact : function(array) {
        return _.select(array, function(value){ return !!value; });
      },
      
      // Return a completely flattened version of an array.
      //            
      //      
      //                
      flatten : function(array) {
        return _.inject(array, [], function(memo, value) {
          //                    
          if (_.isArray(value)) return memo.concat(_.flatten(value));
          memo.push(value);
          return memo;
        });
      },
      
      // Return a version of the array that does not contain the specified value(s).
      //           
      //       ,          array
      //                array slice  arguments
      
      without : function(array) {
        var values = array.slice.call(arguments, 0);
        return _.select(array, function(value){ return !_.include(values, value); });
      },
      
      // Produce a duplicate-free version of the array. If the array has already
      // been sorted, you have the option of using a faster algorithm.
      //      。                ,           
      uniq : function(array, isSorted) {
        return _.inject(array, [], function(memo, el, i) {
          if (0 == i || (isSorted ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
          return memo;
        });
      },
      
      // Produce an array that contains every item shared between all the 
      // passed-in arrays.
      //             
      intersect : function(array) {
        var rest = _.toArray(arguments).slice(1);
        //         
        //           。
        //         
        return _.select(_.uniq(array), function(item) {
          return _.all(rest, function(other) { 
            //        
            //          item                            
            return _.indexOf(other, item) >= 0;
          });
        });
      },
      
      // Zip together multiple lists into a single array -- elements that share
      // an index go together.
      zip : function() {
        var args = _.toArray(arguments);
        var length = _.max(_.pluck(args, 'length'));
        //          。
        var results = new Array(length);
        //        
        for (var i=0; i    
        var fn = new Function('obj', 
          'var p=[],print=function(){p.push.apply(p,arguments);};' +
          'with(obj){p.push(\'' +
          str
            .replace(/[\r\t
    ]/g, " ") .split(")[^\t]*)'/g, "$1\r") .replace(/\t=(.*?)%>/g, "',$1,'") .split("\t").join("');") .split("%>").join("p.push('") .split("\r").join("\\'") + "');}return p.join('');"); return data ? fn(data) : fn; } };

    まとめ
  • の後ろのテンプレートはとても明るい目を実現します.
  • try catch設計eachのジャンプ.
  • >>半分のショートカット
  • 関数の多重化.(一部は非効率かもしれない)
  • のバージョン全体が前です.現代apiの影を見ることができます
  • ソースコードの幅は少なく、注釈を加えても400行程度にすぎない.全編を読んでも大きな障害はありませんが、多重性が比較的高いのですが、testファイルに向かってテスト例を見ればいいのです~~~
  • これらの場所から連絡してください.
    私のブログ私のメールアドレス:[email protected]