当前位置: 代码迷 >> JavaScript >> underscore.js 学习(1)
  详细解决方案

underscore.js 学习(1)

热度:569   发布时间:2013-08-25 10:49:56.0
underscore.js 学习(一)

??????? 工作中需要用到underscore.js,发现这是一个包括了很多基本功能函数的js库,里面有很多实用的函数。而且它没有扩展 javascript的原生对象。主要涉及对Collection、Object、Array、Function的操作。
?????? 学习官方网址:http://underscorejs.org。

?????? Collection Functions (Arrays or Objects) 【集合函数】

??????? 1.each ? _.each(list, iterator, [context]) Alias: forEach

??????? 迭代list中的所有元素,按顺序用迭代器输出每个元素。如果传递了context参数,则把iterator绑定到context对象上。每次调用iterator都会传递三个参数:(element, index, list)。如果list是个JavaScript对象,iterator的参数是 (value, key, list)。存在原生的forEach方法,Underscore就委托给forEach。

//_.each
_.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
_.each({one : 1, two : 2, three : 3}, function(num, key){ console.log(key); });
//  one,two,three

????????

??????? 2.map? _.map(list, iterator, [context]) Alias: collect

用转换函数把list中的每个值映射到一个新的数组。如果list是个JavaScript对象,iterator的参数是(value, key, list),这里的用法和each一样。 mapeach 的区别就是map可以接受返回值。

//_.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]
var r = _.map({one : 1, two : 2, three : 3}, function(num, key) {
    return key;
});
console.log(r); //["one", "two", "three"]

????????

??????? 3.reduce? _.reduce(list, iterator, memo, [context]) Aliases: inject, foldl

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

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

???????? 这个函数有些浏览器提供了原生的,如下的underscore源代码可以很好的帮忙理解此函数。

// 代码的前面就声明了一个变量,检测是否支持原生reduce:
var nativeReduce = ArrayProto.reduce;

?

// **Reduce** builds up a single result from a list of values, aka `inject`,
  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
    var initial = arguments.length > 2;
    if (obj == null) obj = [];
    if (nativeReduce && obj.reduce === nativeReduce) {
      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(reduceError);
    return memo;
  };

???????? 解释上面的例子1就是:试用迭代器把obj(1,2,3)里面的元素相加,由于设置了初始值(0),那就先加初始值,每次的相加的值都存储在memo里面。所以结果是0+1+2+3=6。

???????

??????? 4.reduceRight? _.reduceRight(list, iterator, memo, [context]) Alias: foldr

??????? reducRight是从右侧开始组合的元素的reduce函数,如果存在JavaScript 1.8版本的reduceRight,则用其代替。Foldr在javascript中不像其它有懒计算的语言那么有用(lazy evaluation:一种求值策略,只有当表达式的值真正需要时才对表达式进行计算)。

//_.reduceRight
var list = [[0, 1], [2, 3], [4, 5]];
var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
console.log(flat); // [4, 5, 2, 3, 0, 1]
    
var list = [[0],[11,22],[33,44,55]];
var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
console.log(flat); // [33, 44, 55, 11, 22, 0]

?

??????? 5.find? _.find(list, iterator, [context]) Alias: detect

??????? 遍历list,返回第一个通过iterator真值检测的元素值。如果找到匹配的元素立即返回,不会遍历整个list。

//_.find
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
console.log(even); //2
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num > 3; });
console.log(even); //4

?

??????? 6.filter? _.filter(list, iterator, [context]) Alias: select

??????? 遍历list,返回包含所有通过iterator真值检测的元素值。如果存在原生filter方法,则委托给filter,

和find不同的是,它返回所有符合条件的值,返回一个数组。

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

?

??????? 7.where?? _.where(list, properties)

??????? 遍历list,返回properties中所有键值对都相等的对象数组。

//_.where
var listOfPlays = [{title: "Cymbeline", author: "Shakespeare", year: 1611},
        {title: "The Tempest", author: "Shakespeare", year: 1631},
        {title: "The Tempest2", author: "Shakespeare", year: 1661},
        {title: "The Tempest3", author: "Shakespeare3", year: 1611},
        {title: "The Tempest4", author: "Shakespeare", year: 1611}];
var r = _.where(listOfPlays, {author: "Shakespeare", year: 1611});
console.log(r);
//[{title: "Cymbeline", author: "Shakespeare", year: 1611},{title: "The Tempest4", author: "Shakespeare", year: 1611}]

?

??????? 8.findWhere?? _.findWhere(list, properties)

??????? 遍历list,返回properties中所有键值对都相等的第一个对象。

//_.findWhere
var listOfPlays = [{title: "Cymbeline", author: "Shakespeare0", year: 1611},
        {title: "The Tempest", author: "Shakespeare", year: 1611},
        {title: "The Tempest2", author: "Shakespeare", year: 1661},
        {title: "The Tempest3", author: "Shakespeare3", year: 1611},
        {title: "The Tempest4", author: "Shakespeare", year: 1611}];
var r = _.findWhere(listOfPlays, {author: "Shakespeare", year: 1611});
console.log(r); //{title: "The Tempest", author: "Shakespeare", year: 1611} 

?

??????? 9.reject ? _.reject(list, iterator, [context])

??????? 返回那么没有通过iterator真值检测的元素数组,filter的相反函数。

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

?

??????? 10.every??? _.every(list, [iterator], [context]) Alias: all

??????? 如果list中的所有元素都通过iterator的真值检测就返回true。如果存在原生的every方法,则委托给every。

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

?

??????? 11.some? _.some(list, [iterator], [context])? Alias: any

??????? 如果有任何一个元素通过通过 iterator 的真值检测就返回true。如果存在原生的some方法,则委托给some。

//_.some
var r = _.some([null, 0, 'yes', false]);
console.log(r); //true
var r = _.some([2, 1, 13, 6, 37, 68], function(num){ return num % 2 == 0; });
console.log(r); //true
var r = _.some([2, 1, 13, 7, 37, 68], function(num){ return num % 3 == 0; });
console.log(r); //false

?

??????? 12.contains??? _.contains(list, value) ?? Alias: include

??????? 如果list包含指定的value则返回true,使用===检测是否相等。如果list 是数组,内部使用indexOf判断。

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

?

??????? 13.