underscore.js

       underscore是一個很是實用的javascript庫,提供許多編程時須要的功能的支持,在不擴展任何javascript原生對象的狀況下提供不少實用的功能。主要涉及對Collection、Object、Array、Function的操做。一共60多個函數。javascript

函數介紹:html

1、Collection Functions (Arrays or Objects) 【集合函數】:java

一、#each# _.each(list, iterator, [context])正則表達式

迭代list中的全部元素,按順序用迭代器輸出每一個元素。若是傳遞了context參數,則把iterator綁定到context對象上。每次調用iterator都會傳遞三個參數:(element, index, list)。若是list是個JavaScript對象,iterator的參數是(value, key, list)。存在原生的forEach方法,Underscore就委託給forEach.編程

_.each([1, 2, 3], function(num){ console.log(num); });
    //  1,2,3
    _.each({one : 1, two : 2, three : 3}, function(num, key){ console.log(num); });
    //  1,2,3

    //  html:

var p = document.getElementsByTagName(‘p’);json

    _.each(p , function( value, key, list ){ 
        console.log( value );  //  p1,p2,p2
        console.log( key  );   //  0,1,2
    })

二、#map# _.map(list, iterator, [context])數組

用轉換函數把list中的每一個值映射到一個新的數組。若是list是個JavaScript對象,iterator的參數是(value, key, list),這裏的用法和each同樣。 map 和 each 的區別就是map能夠接受返回值。瀏覽器

var r = _.map([1, 2, 3], function(num){ return num * 3; });
    console.log(r); //   [3, 6, 9]
    var r = _.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; });
    console.log(r); //   [3, 6, 9]

三、#reduce# _.reduce(list, iterator, memo, [context])app

reduce方法把列表中元素歸結爲一個簡單的數值,Memo是reduce函數的初始值,reduce的每一步都須要由iterator返回。curl

 var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
    // 6

這個函數有些瀏覽器提供了原生的,可是對不知道的童鞋,可能很難經過這個例子明白函數的試用方法,好的,看源碼:

    // 代碼的前面就聲明瞭一個變量,檢測是否支持原生reduce:
    var nativeReduce = ArrayProto.reduce;

    _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
        var initial = arguments.length > 2;
        if (obj == null) obj = [];
        if (nativeReduce && obj.reduce === nativeReduce) {      
            // 使用原生的reduce
            if (context) iterator = _.bind(iterator, context);
            return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
        }
        each(obj, function(value, index, list) {
            if (!initial) {
                memo = value;
                initial = true;
            } else {
                memo = iterator.call(context, memo, value, index, list);
            }
        });
        if (!initial) throw new TypeError('Reduce of empty array with no initial value');
        return memo;
    };

解釋上面的例子就是:試用迭代器把obj(1,2,3)裏面的元素相加,因爲設置了初始值(0),那就先加初始值,每次的相加的值都存儲在memo裏面。因此結果是0+1+2+3=6。

四、#reduceRight# _.reduceRight(list, iterator, memo, [context])

reducRight是從右側開始組合的元素的reduce函數,若是存在JavaScript 1.8版本的reduceRight,則用其代替。Foldr在javascript中不像其它有懶計算的語言那麼有用(lazy evaluation:一種求值策略,只有當表達式的值真正須要時纔對表達式進行計算)。

    var list = [[0, 1], [2, 3], [4, 5]];
    var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
    => [4, 5, 2, 3, 0, 1]

五、#find# _.find(list, iterator, [context])

遍歷list,返回第一個經過iterator真值檢測的元素值。若是找到匹配的元素當即返回,不會遍歷整個list。

var r = _.find([1, 2, 3, 4, 5, 6], function(num){ 
        if(num > 3) return true;
    });
    // r == 4

六、#filter# _.filter(list, iterator, [context])

遍歷list,返回包含全部經過iterator真值檢測的元素值。若是存在原生filter方法,則委託給filter, 和find不一樣的是,它返回全部符合條件的值,返回一個數組。

var r = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
    // r == [2, 4, 6]

七、#reject# _.reject(list, iterator, [context])

返回那麼沒有經過iterator真值檢測的元素數組,filter的相反函數。

var r = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
    //r == [1, 3, 5]

八、#all# _.all(list, iterator, [context])

若是list中的全部元素都經過iterator的真值檢測就返回true。若是存在原生的every方法,則委託給every。

var r = _.all([2, 22, 12, 4, 34, 68], function(num){ return num % 2 == 0; });
    // r == true;

九、#any#  _.any(list, [iterator], [context])

若是有任何一個元素經過經過 iterator 的真值檢測就返回true。若是存在原生的some方法,則委託給some。

var r = _.all([2, 1, 13, 6, 37, 68], function(num){ return num % 2 == 0; });
    // r == true;

十、#contains# _.contains(list, value)

若是list包含指定的value則返回true,使用===檢測是否相等。若是list 是數組,內部使用indexOf判斷。

var r = _.contains([1, 2, 3], 3);
    // r == true
    _.contains({one:1,two:2},1);
    // r == true

十一、#invoke#_.invoke(list, methodName, [*arguments])

在list的每一個元素上執行methodName方法。若是有額外的參數,則在調用methodName方法的時候傳給它。

_.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); 
// [[1, 5, 7], [1, 2, 3]] 
// 進行排序操做

十二、#pluck#_.pluck(list, propertyName)

提取對象中的一個屬性,返回一個數組。

var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]; 
_.pluck(stooges, 'name'); 
// ["moe", "larry", "curly"]

1三、#max#_.max(list, [iterator], [context])

返回list中的最大值,迭代器可選,若是有,則以迭代器做爲排序依據。

var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]; 
_.max(stooges, function(stooge){ return stooge.age; }); 
// {name : 'curly', age : 60};

1四、#min#_.min(list, [iterator], [context])

返回list中的最小值,迭代器可選,若是有,則以迭代器做爲排序依據。

var numbers = [10, 5, 100, 2, 1000]; 
_.min(numbers); // 2

1五、#sortBy#_.sortBy(list, iterator, [context])

返回一個經過升序排序後的一個數組(新的數組),若是有迭代器,以迭代器做爲排序依據。

_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); }); 
// [5, 4, 6, 3, 1, 2]

1六、#groupBy#_.groupBy(list, iterator)

經過迭代器返回的值分組,生成一個json對象。迭代器也能夠是一個字符串,經過調用元素對應的屬性分組。

_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); }); 
// {1: [1.3], 2: [2.1, 2.4]} 

_.groupBy(['one', 'two', 'three'], 'length'); 
// {3: ["one", "two"], 5: ["three"]}

1七、#countBy#_.countBy(list, iterator)

對list進行分組,返回一個json對象,對應的鍵值對是:分組名(在迭代器裏面設置)和數量。

_.countBy([1, 2, 3, 4, 5], function(num) { return num % 2 == 0 ? 'even' : 'odd'; }); 
// {odd: 3, even: 2}

1八、#shuffle#_.shuffle(list)

返回一個打亂了的list數組副本。

_.shuffle([1, 2, 3, 4, 5, 6]); 
// [4, 1, 6, 3, 5, 2]

1九、#toArray#_.toArray(list)

轉換list爲數組,對有參數對象的轉換頗有用。

(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4); 
// [2, 3, 4]

20、#size#_.size(list)

返回list的長度

 _.size({one:1,two:2}); // 2

 

2、Array Functions【數組函數】:

一、#first# _.first(array, [n])

返回array的第一個元素,設置了參數n,就返回前n個元素。

    _.first([5, 4, 3, 2, 1]);
    // 5
    _.first([5,4,3,2,1],3);
    // [5,4,3]

二、#last# _.last(array,[n])

返回list的最後一個元素,設置參數n,則返回最後n個元素。

    _.last([5, 4, 3, 2, 1]);
    // 1
    _.last([5, 4, 3, 2, 1],2);
    // [2,1]

三、#initial# _.initial(array, [n])

返回除了最後一個元素之外的全部元素。對參數對象特別有用。設置了參數n,就排除最後n個元素。

    _.initial([5, 4, 3, 2, 1]);
    // [5, 4, 3, 2]
    _.initial([5, 4, 3, 2, 1] , 3);
    // [5, 4]

四、#rest# _.rest(array, [index])

返回除了第一個元素之外的全部元素。設置了參數n,就排除前n個元素。

 _.rest([5, 4, 3, 2, 1]);
    // [4, 3, 2, 1]
    _.rest([5, 4, 3, 2, 1],2);
    // [3, 2, 1]

五、#compact# _.compact(array)

返回一個去除了false值的元素的數組副本。在javascript裏,false,null,0,「」,undefined,NaN是false值。

    _.compact([0, 1, false, 2, '', 3]);
    // [1, 2, 3]

六、#flatten# _.flatten(array, [shallow])

展開一個嵌套數組(能夠是任何嵌套級數),若是設置了參數shallow,就只能展開一個等級。

    _.flatten([1, [2], [3, [[4]]]]);
    // [1, 2, 3, 4];

    _.flatten([1, [2], [3, [[4]]]], true);
    // [1, 2, 3, [[4]]];

七、#without# _.without(array, [*values])

返回一個去處了values以後的數組副本。

    _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
    // [2, 3, 4]

八、#union# _.union(*arrays)

計算傳入的 arrays(數組)並集:按順序返回一個存在於一個或多個 arrays(數組)中獨一無二的項目列表。

    _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
    // [1, 2, 3, 101, 10]

九、#intersection# _.intersection(*arrays)

計算數組的交集:每一個值都出如今每一個是數組裏。

    _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
    // [1, 2]

十、#difference _.difference(array, *others)

和without差很少,不過它返回的是不在其餘數組裏面的值。

    _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
    // [1, 3, 4]

十一、#uniq# _.uniq(array, [isSorted], [iterator])

去除數組重複,使用===測試。若是你肯定數組已經排序,就傳遞true給isSorted。返回新的數組副本。

    _.uniq([1, 2, 1, 3, 1, 4]);
    // [1, 2, 3, 4]

十二、#zip# _.zip(*arrays)

在對應的位置合併每個數組元素,當你有單獨的有用數據源時經過匹配數組索引協調。若是您正在使用嵌套的數組矩陣,zip.apply能夠轉置矩陣類似的方式。

    _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
    // [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]

1三、#object# _.object(list, [values])

把數組變成對象,能夠傳入鍵值對,也能夠傳入一個鍵數組,一個值數組。

    _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
    // {moe: 30, larry: 40, curly: 50}

    _.object([['moe', 30], ['larry', 40], ['curly', 50]]);
    // {moe: 30, larry: 40, curly: 50}

1四、#indexOf# _.indexOf(array, value, [isSorted])

返回值在數組裏面的索引,-1表示找不到。傳true給isSorted,表示數組已經排序,能夠提升速度。

    _.indexOf([1, 2, 3], 2);
    // 1

1五、#lastIndexOf# _.lastIndexOf(array, value, [fromIndex])

返回value在array最後開始的索引值,沒有則返回-1。

    _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
    // 4

1六、#sortedIndex# _.sortedIndex(list, value, [iterator])

運用二進制搜索,查找value在list裏面可插入的位置,傳true給isSorted,表示數組已經排序,能夠提升速度。

    _.sortedIndex([10, 20, 30, 40, 50], 35);
    // 3

1七、#range# _.range([start], stop, [step])

一個用來建立整數靈活編號的列表的函數,便於each 和 map循環。若是省略start則默認爲 0;step 默認爲 1.返回一個從start 到stop的整數的列表,用step來增長 (或減小)獨佔。

    _.range(10);
    // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    _.range(1, 11);
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    _.range(0, 30, 5);
    // [0, 5, 10, 15, 20, 25]
    _.range(0, -10, -1);
    // [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
    _.range(0);
    // []

 

 3、Functions 【函數】

一、#bind# _.bind(function, object, [*arguments])

綁定一個函數到一個對象上面,無論何時調用函數,this指針都是指向對象。也能夠爲函數綁定參數

    var func = function(greeting){ return greeting + ': ' + this.name };
    func = _.bind(func, {name : 'moe'}, 'hi');
    func();
    // 'hi: moe'

二、#bindAll# _.bindAll(object, [*methodNames])

把methodNames參數指定的方法綁定到對象上,這些方法就會在對象的上下文環境中執行。綁定函數用做事件處理函數時很是便利,不然函數被調用時this一點用也沒有。若是不設置methodNames參數,對象上的全部方法都會被綁定。

    var buttonView = {
      label   : 'underscore',
      onClick : function(){ alert('clicked: ' + this.label); },
      onHover : function(){ console.log('hovering: ' + this.label); }
    };
    _.bindAll(buttonView);
    jQuery('#underscore_button').bind('click', buttonView.onClick);
    // When the button is clicked, this.label will have the correct value...

三、#memoize# _.memoize(function, [hashFunction])

記錄函數的計算結果。對比較耗時的計算有幫助。若是設置了參數hashFunction,就用hashFunction的返回值做爲key存儲函數的計算結果。 hashFunction默認使用function的第一個參數做爲key.

    var fibonacci = _.memoize(function(n) {
      return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
    });

四、#delay# _.delay(function, wait, [*arguments])

和setTimeout差很少,在wait時間後調用函數,若是設置了參數,就在調用函數時,傳遞參數。

    var log = _.bind(console.log, console);
    _.delay(log, 1000, 'logged later');
    // 'logged later'

五、#defer# _.defer(function, [*arguments])

延遲執行函數知道當前棧被清空,和delay爲0的setTimeout差很少。對HTML無阻賽渲染有幫助。若是設置了參數,就在函數調用時傳遞進去。

    _.defer(function(){ alert('deferred'); });
    // Returns from the function before the alert runs.

六、#throttle# _.throttle(function, wait)

建立並返回一個節流版本的函數,當重複調用函數時,就強制間隔wait時段才執行。

    var throttled = _.throttle(updatePosition, 100);
    $(window).scroll(throttled);

七、#debounce# _.debounce(function, wait, [immediate])

建立並返回一個控制函數,當該函數被調用,wait毫秒後才執行,wait毫秒期間若是再次觸發則從新計時。

    var lazyLayout = _.debounce(calculateLayout, 300);
    $(window).resize(lazyLayout);

八、#once# _.once(function)

建立返回一個一次性函數。調用以後就不能再調用了。

    var initialize = _.once(createApplication);
    initialize();
    initialize();
    // Application is only created once.

九、#after# _.after(count, function)

建立返回一個函數,在這個函數別調用了count次以後,纔開始運行裏面的function。

    var a = _.after(5,fun);
    $(window).click(a);

十、#wrap# _.wrap(function, wrapper)

把第一個函數包裹在包裹器裏。

    var hello = function(name) { return "hello: " + name; };
    hello = _.wrap(hello, function(func) {
      return "before, " + func("moe") + ", after";
    });
    hello();
    // 'before, hello: moe, after'

十一、#compose# _.compose(*functions)

返回一個函數列的組合物,其中每一個函數的參數是其後跟隨函數的返回值。在數學關係上,f() g()和h()函數的組合產生f(g(h()))。

    var greet    = function(name){ return "hi: " + name; };
    var exclaim  = function(statement){ return statement + "!"; };
    var welcome = _.compose(exclaim, greet);
    welcome('moe');
    // 'hi: moe!'

4、Object【對象】

一、#keys# _.keys(object)

返回一個裝有object的鍵的數組

    _.keys({one : 1, two : 2, three : 3});
    => ["one", "two", "three"]

二、#values# _.values(object)

返回一個裝有object的值的數組

    _.values({one : 1, two : 2, three : 3});
    => [1, 2, 3]

三、#pairs# _.pairs(object)

把對象的鍵值對轉變爲一個二維數組,並放到一個大的數組內

    _.pairs({one: 1, two: 2, three: 3});
    => [["one", 1], ["two", 2], ["three", 3]]

四、#invert# _.invert(object)

複製一個對象,把object的鍵值反轉返回。

    _.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"}); => {Moses: "Moe", Louis: "Larry", Jerome: "Curly"};

五、#functions# _.functions(object)

返回一個數組,裏面裝有object的全部函數名稱

    _.functions(_);
    => ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...

六、#extend# _.extend(destination, *sources)

擴展,源對象將覆蓋或者建立目標對象的屬性

    var a = {name : 'moe'}
    _.extend(a, {age : 50});
    => a ==  {name : 'moe', age : 50}

七、#pick# _.pick(object, *keys)

經過keys從object選擇出鍵值對,放到一個新建的object返回

ps:keys也能夠是一個包含有效鍵的數組

    _.pick({name : 'moe', age: 50, userid : 'moe1'}, 'name', 'age');
    => {name : 'moe', age : 50}
    _.pick({name : 'moe', age: 50, userid : 'moe1'}, ['name', 'age']);
    => {name : 'moe', age : 50}

八、#omit# _.omit(object, *keys)

經過keys忽略object裏面的鍵值對,剩下的放入一個新建的對象返回。

ps:keys也能夠是一個包含有效鍵的數組,基本跟pick相反

    _.omit({name : 'moe', age : 50, userid : 'moe1'}, 'userid');
    => {name : 'moe', age : 50}

九、#defaults# _.defaults(object,*defaults)

爲對象設置默認值,若是對象沒有設置值,則就調用默認值。

    var iceCream = {flavor : "chocolate"};
    _.defaults(iceCream, {flavor : "vanilla", sprinkles : "lots"});
    => {flavor : "chocolate", sprinkles : "lots"}

十、#clone# _.clone(object)

淺複製

    _.clone({name : 'moe'});
    => {name : 'moe'};

十一、#tap_.tap(object ,interceptor)

摸索中

    _.chain([1,2,3,200])
      .filter(function(num) { return num % 2 == 0; })
      .tap(alert)
      .map(function(num) { return num * num })
      .value();
    => // [2, 200] (alerted)
    => [4, 40000]

十二、#has# _.has(object, key)

判斷object是否含有給出的key

    _.has({a: 1, b: 2, c: 3}, "b");
    => true

1三、#isEqual# _.isEqual(object, ohter)

深度對比了兩個object是否相等

    var moe   = {name : 'moe', luckyNumbers : [13, 27, 34]};
    var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
    moe == clone;
    => false
    _.isEqual(moe, clone);
    => true

1四、#isEmpty#_.isEmpty(object)

object是否爲空

    _.isElement(jQuery('body')[0]);
    => true

1五、#isArray# _.isArray(object)

object是否爲數組

    (function(){ return _.isArray(arguments); })();
    => false
    _.isArray([1,2,3]);
    => true 

1六、#isObject# _.isObject(object)

object是否爲對象

    _.isObject({});
    => true
    _.isObject(1);
    => false

1七、#isArguments# _.isArguments(object)

object是否爲參數對象

    (function(){ return _.isArguments(arguments); })(1, 2, 3);
    => true
    _.isArguments([1,2,3]);
    => false

1八、#isFunction#_.isFunction(object)

object是否爲函數

   _.isFunction(alert);
    => true

1九、#isString# _.isString(object)

object是否爲字符串

    _.isString("moe");
    => true

20、#isNumber_.isNumber(object)

object是否爲數字

    _.isNumber(8.4 * 5);
    => true

2一、#isFinite# _.isFinite(object)

object是否爲有限數

   _.isFinite(-101);
    => true
    _.isFinite(-Infinity);
    => false

2二、#isBoolean# _.isBoolean(object)

object是否爲布爾值

    _.isBoolean(null);
    => false    

2三、#isDate# _.isDate(object)

object是否爲日期

    _.isDate(new Date());
    => true

2四、#isRegExp# _.isRegExp(object)

object是否爲正則表達式

    _.isRegExp(/moe/);
    => true

2五、#isNaN# _.isNaN(object)

object是否爲NaN

    _.isNaN(NaN);
    => true
    isNaN(undefined);
    => true
    _.isNaN(undefined);
    => false

2六、#isNull# _.isNull(object)

object是否爲Null

    _.isNull(null);
    => true
    _.isNull(undefined);
    => false

2七、#isUndefined# _.isUndefined(object)

object是否爲undefined

    _.isUndefined(window.missingVariable);
    => true
相關文章
相關標籤/搜索