underscore.js

       underscore是一个非常实用的javascript库,提供许多编程时需要的功能的支持,在不扩展任何javascript原生对象的情况下提供很多实用的功能。主要涉及对Collection、Object、Array、Function的操作。一共60多个函数。

函数介绍:

一、Collection Functions (Arrays or Objects) 【集合函数】:

1、#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’);

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

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]

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

reduce方法把列表中元素归结为一个简单的数值,Memo是reduce函数的初始值,reduce的每一步都需要由iterator返回。

 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。

4、#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]

5、#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

6、#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]

7、#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]

8、#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;

9、#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;

10、#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

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

在list的每个元素上执行methodName方法。如果有额外的参数,则在调用methodName方法的时候传给它。

_.invoke([[5, 1, 7], [3, 2, 1]], ‘sort‘); 
// [[1, 5, 7], [1, 2, 3]] 
// 进行排序操作

12、#pluck#_.pluck(list, propertyName)

提取对象中的一个属性,返回一个数组。

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

13、#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};

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

返回list中的最小值,迭代器可选,如果有,则以迭代器作为排序依据。

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

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

返回一个通过升序排序后的一个数组(新的数组),如果有迭代器,以迭代器作为排序依据。

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

16、#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"]}

17、#countBy#_.countBy(list, iterator)

对list进行分组,返回一个json对象,对应的键值对是:分组名(在迭代器里面设置)和数量。

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

18、#shuffle#_.shuffle(list)

返回一个打乱了的list数组副本。

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

19、#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

 

二、Array Functions【数组函数】:

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

返回array的第一个元素,设置了参数n,就返回前n个元素。

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

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

返回list的最后一个元素,设置参数n,则返回最后n个元素。

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

3、#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]

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]

5、#compact# _.compact(array)

返回一个去除了false值的元素的数组副本。在javascript里,false,null,0,“”,undefined,NaN是false值。

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

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

展开一个嵌套数组(可以是任何嵌套级数),如果设置了参数shallow,就只能展开一个等级。

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

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

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

返回一个去处了values之后的数组副本。

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

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

计算传入的 arrays(数组)并集:按顺序返回一个存在于一个或多个 arrays(数组)中独一无二的项目列表。

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

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

计算数组的交集:每个值都出现在每个是数组里。

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

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

和without差不多,不过它返回的是不在其他数组里面的值。

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

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

去除数组重复,使用===测试。如果你确定数组已经排序,就传递true给isSorted。返回新的数组副本。

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

12、#zip# _.zip(*arrays)

在对应的位置合并每一个数组元素,当你有单独的有用数据源时通过匹配数组索引协调。如果您正在使用嵌套的数组矩阵,zip.apply可以转置矩阵相似的方式。

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

13、#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}

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

返回值在数组里面的索引,-1表示找不到。传true给isSorted,表示数组已经排序,可以提高速度。

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

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

返回value在array最后开始的索引值,没有则返回-1。

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

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

运用二进制搜索,查找value在list里面可插入的位置,传true给isSorted,表示数组已经排序,可以提高速度。

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

17、#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);
    // []

 

 三、Functions 【函数】

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

绑定一个函数到一个对象上面,不管什么时候调用函数,this指针都是指向对象。也可以为函数绑定参数

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

2、#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...

3、#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);
    });

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

和setTimeout差不多,在wait时间后调用函数,如果设置了参数,就在调用函数时,传递参数。

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

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

延迟执行函数知道当前栈被清空,和delay为0的setTimeout差不多。对HTML无阻赛渲染有帮助。如果设置了参数,就在函数调用时传递进去。

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

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

创建并返回一个节流版本的函数,当重复调用函数时,就强制间隔wait时段才执行。

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

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

创建并返回一个控制函数,当该函数被调用,wait毫秒后才执行,wait毫秒期间如果再次触发则重新计时。

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

8、#once# _.once(function)

创建返回一个一次性函数。调用之后就不能再调用了。

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

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

创建返回一个函数,在这个函数别调用了count次之后,才开始运行里面的function。

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

10、#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‘

11、#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!‘

四、Object【对象】

1、#keys# _.keys(object)

返回一个装有object的键的数组

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

2、#values# _.values(object)

返回一个装有object的值的数组

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

3、#pairs# _.pairs(object)

把对象的键值对转变为一个二维数组,并放到一个大的数组内

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

4、#invert# _.invert(object)

复制一个对象,把object的键值反转返回。

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

5、#functions# _.functions(object)

返回一个数组,里面装有object的所有函数名称

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

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

扩展,源对象将覆盖或者创建目标对象的属性

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

7、#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}

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

通过keys忽略object里面的键值对,剩下的放入一个新建的对象返回。

ps:keys也可以是一个包含有效键的数组,基本跟pick相反

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

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

为对象设置默认值,如果对象没有设置值,则就调用默认值。

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

10、#clone# _.clone(object)

浅复制

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

11、#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]

12、#has# _.has(object, key)

判断object是否含有给出的key

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

13、#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

14、#isEmpty#_.isEmpty(object)

object是否为空

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

15、#isArray# _.isArray(object)

object是否为数组

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

16、#isObject# _.isObject(object)

object是否为对象

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

17、#isArguments# _.isArguments(object)

object是否为参数对象

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

18、#isFunction#_.isFunction(object)

object是否为函数

   _.isFunction(alert);
    => true

19、#isString# _.isString(object)

object是否为字符串

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

20、#isNumber_.isNumber(object)

object是否为数字

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

21、#isFinite# _.isFinite(object)

object是否为有限数

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

22、#isBoolean# _.isBoolean(object)

object是否为布尔值

    _.isBoolean(null);
    => false    

23、#isDate# _.isDate(object)

object是否为日期

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

24、#isRegExp# _.isRegExp(object)

object是否为正则表达式

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

25、#isNaN# _.isNaN(object)

object是否为NaN

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

26、#isNull# _.isNull(object)

object是否为Null

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

27、#isUndefined# _.isUndefined(object)

object是否为undefined

    _.isUndefined(window.missingVariable);
    => true

underscore.js,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。