实用功能(Utility Functions)
noConflict
_.noConflict()
放弃Underscore 的控制变量 _。返回Underscore 对象的引用。
var underscore = _.noConflict();
identity
_.identity(value)
返回与传入参数相等的值. 相当于数学里的: f(x) = x
这个函数看似无用, 但是在Underscore里被用作默认的迭代器iterator.
var stooge = {name: 'moe'}; stooge === _.identity(stooge); => true
constant
_.constant(value)
创建一个函数,这个函数 返回相同的值 用来作为_.constant的参数。
var stooge = {name: 'moe'}; stooge === _.constant(stooge)(); => true
noop
_.noop()
返回undefined,不论传递给它的是什么参数。 可以用作默认可选的回调参数。
obj.initialize = _.noop;
times
_.times(n, iteratee, [context])
调用给定的迭代函数n次,每一次调用iteratee传递index参数。生成一个返回值的数组。
_.times(3, function(n){ genie.grantWishNumber(n); });
random
_.random(min, max)
返回一个min 和 max之间的随机整数。如果你只传递一个参数,那么将返回0和这个参数之间的整数。
_.random(0, 100);
=> 42
mixin
_.mixin(object)
允许用您自己的实用程序函数扩展Underscore。传递一个 {name: function}定义的哈希添加到Underscore对象,以及面向对象封装。
_.mixin({ capitalize: function(string) { return string.charAt(0).toUpperCase()+string.substring(1).toLowerCase(); } }); _("fabio").capitalize(); => "Fabio"
iteratee
_.iteratee(value, [context])
生成可应用于集合中的每个元素的回调。_.iteratee支持许多常见回调用例的简写语法。根据值的类型,_.iteratee 将返回:
// No value _.iteratee(); => _.identity() // Function _.iteratee(function(n) { return n * 2; }); => function(n) { return n * 2; } // Object _.iteratee({firstName: 'Chelsea'}); => _.matcher({firstName: 'Chelsea'}); // Anything else _.iteratee('firstName'); => _.property('firstName');
通过_.iteratee转换判断的Underscore 方法的完整列表是: countBy, every, filter, find, findIndex, findKey, findLastIndex, groupBy, indexBy, map, mapObject, max, min, partition, reject, some, sortBy, sortedIndex, and uniq
如果您需要其他或不同的简写语法,可以使用自己的自定义函数覆盖 _.iteratee:
// Support `RegExp` predicate shorthand. var builtinIteratee = _.iteratee; _.iteratee = function(value, context) { if (_.isRegExp(value)) return function(obj) { return value.test(obj) }; return builtinIteratee(value, context); };
uniqueId
_.uniqueId([prefix])
为需要的客户端模型或DOM元素生成一个全局唯一的id。如果prefix参数存在, id 将附加给它。
_.uniqueId('contact_');
=> 'contact_104'
escape
_.escape(string)
转义HTML字符串,替换&, <, >, ", ', 和 /字符。
_.escape('Curly, Larry & Moe');
=> "Curly, Larry & Moe"
unescape
_.unescape(string)
和escape相反。转义HTML字符串,替换&, <, >, ", `, 和 /字符。
_.unescape('Curly, Larry & Moe');
=> "Curly, Larry & Moe"
result
_.result(object, property, [defaultValue])
如果指定的property 的值是一个函数,那么将在object上下文内调用它;否则,返回它。如果提供默认值,并且属性不存在,那么默认值将被返回。如果设置defaultValue是一个函数,它的结果将被返回。
var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }}; _.result(object, 'cheese'); => "crumpets" _.result(object, 'stuff'); => "nonsense" _.result(object, 'meat', 'ham'); => "ham"
now
_.now()
一个优化的方式来获得一个当前时间的整数时间戳。可用于实现定时/动画功能。
_.now();
=> 1392066795351
template
_.template(templateString, [settings])
将 JavaScript 模板编译为可以用于页面呈现的函数, 对于通过JSON数据源生成复杂的HTML并呈现出来的操作非常有用。 模板函数可以使用 <%= … %>插入变量, 也可以用<% … %>执行任意的 JavaScript 代码。 如果您希望插入一个值, 并让其进行HTML转义,请使用<%- … %>。 当你要给模板函数赋值的时候,可以传递一个含有与模板对应属性的data对象 。 如果您要写一个一次性的, 您可以传对象 data 作为第二个参数给模板 template 来直接呈现, 这样页面会立即呈现而不是返回一个模板函数. 参数 settings 是一个哈希表包含任何可以覆盖的设置 _.templateSettings.
var compiled = _.template("hello: <%= name %>"); compiled({name: 'moe'}); => "hello: moe" var template = _.template("<b><%- value %></b>"); template({value: '<script>'}); => "<b><script></b>" 您也可以在 JavaScript 代码中使用 print. 有时候这会比使用 <%= ... %> 更方便. var compiled = _.template("<% print('Hello ' + epithet); %>"); compiled({epithet: "stooge"}); => "Hello stooge"
如果ERB式的分隔符您不喜欢, 您可以改变Underscore的模板设置, 使用别的符号来嵌入代码.定义一个 interpolate 正则表达式来逐字匹配嵌入代码的语句, 如果想插入转义后的HTML代码则需要定义一个 escape 正则表达式来匹配,还有一个 evaluate 正则表达式来匹配您想要直接一次性执行程序而不需要任何返回值的语句.您可以定义或省略这三个的任意一个.例如, 要执行Mustache.js类型的模板:
_.templateSettings = { interpolate: /\{\{(.+?)\}\}/g }; var template = _.template("Hello {{ name }}!"); template({name: "Mustache"}); => "Hello Mustache!"
默认的, template 通过 with 语句来取得 data 所有的值. 当然, 您也可以在 variable 设置里指定一个变量名. 这样能显著提升模板的渲染速度.
_.template("Using 'with': <%= data.answer %>", {variable: 'data'})({answer: 'no'});
=> "Using 'with': no"
预编译模板对调试不可重现的错误很有帮助. 这是因为预编译的模板可以提供错误的代码行号和堆栈跟踪, 有些模板在客户端(浏览器)上是不能通过编译的 在编译好的模板函数上, 有 source 属性可以提供简单的预编译功能.
<script> JST.project = <%= _.template(jstText).source %>; </script>
Object-Oriented Style
您可以在面向对象或者函数的风格下使用Underscore, 这取决于您的个人偏好. 以下两行代码都可以 把一个数组里的所有数字乘以2.
_.map([1, 2, 3], function(n){ return n * 2; }); _([1, 2, 3]).map(function(n){ return n * 2; });
链式语法(Chaining)
对一个对象使用 chain 方法, 会把这个对象封装并 让以后每次方法的调用结束后都返回这个封装的对象, 当您完成了计算, 可以使用 value 函数来取得最终的值. 以下是一个同时使用了 map/flatten/reduce 的链式语法例子, 目的是计算一首歌的歌词里每一个单词出现的次数.
var lyrics = [ {line: 1, words: "I'm a lumberjack and I'm okay"}, {line: 2, words: "I sleep all night and I work all day"}, {line: 3, words: "He's a lumberjack and he's okay"}, {line: 4, words: "He sleeps all night and he works all day"} ]; _.chain(lyrics) .map(function(line) { return line.words.split(' '); }) .flatten() .reduce(function(counts, word) { counts[word] = (counts[word] || 0) + 1; return counts; }, {}) .value(); => {lumberjack: 2, all: 4, night: 2 ... }
此外, 数组原型方法 也通过代理加入到了链式封装的Underscore对象, 所以您可以 在链式语法中直接使用 reverse 或 push 方法, 然后再接着其他的语句.
chain
_.chain(obj)
返回一个封装的对象. 在封装的对象上调用方法会返回封装的对象本身, 直道 value 方法调用为止。
var stooges = [{name: 'curly', age: 25}, {name: 'moe', age: 21}, {name: 'larry', age: 23}]; var youngest = _.chain(stooges) .sortBy(function(stooge){ return stooge.age; }) .map(function(stooge){ return stooge.name + ' is ' + stooge.age; }) .first() .value(); => "moe is 21"
value
_.chain(obj).value()
获取封装对象的最终值。
_.chain([1, 2, 3]).reverse().value();
=> [3, 2, 1]