root = this
diff --git a/documentation/docs/underscore.html b/documentation/docs/underscore.html index d3177f74..e8d86f5c 100644 --- a/documentation/docs/underscore.html +++ b/documentation/docs/underscore.html @@ -1,295 +1,1892 @@ -
underscore.coffee | |
---|---|
Underscore.coffee
+
+
+
+
+ Underscore.coffee
(c) 2011 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
+Prototype.js, Oliver Steele's
+Functional, and John Resig's
Micro-Templating.
For all details and documentation:
-http://documentcloud.github.com/underscore/ | |
Baseline setup | |
Establish the root object, | root = this |
Save the previous value of the | previousUnderscore = root._ |
Establish the object that gets thrown to break out of a loop iteration.
- | breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration |
Helper function to escape RegExp contents, because JS doesn't have one. | escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1') |
Save bytes in the minified (but not gzipped) version: | ArrayProto = Array.prototype
-ObjProto = Object.prototype |
Create quick reference variables for speed access to core prototypes. | slice = ArrayProto.slice
-unshift = ArrayProto.unshift
-toString = ObjProto.toString
-hasOwnProperty = ObjProto.hasOwnProperty
-propertyIsEnumerable = ObjProto.propertyIsEnumerable |
All ECMA5 native implementations we hope to use are declared here. | nativeForEach = ArrayProto.forEach
-nativeMap = ArrayProto.map
-nativeReduce = ArrayProto.reduce
-nativeReduceRight = ArrayProto.reduceRight
-nativeFilter = ArrayProto.filter
-nativeEvery = ArrayProto.every
-nativeSome = ArrayProto.some
-nativeIndexOf = ArrayProto.indexOf
-nativeLastIndexOf = ArrayProto.lastIndexOf
-nativeIsArray = Array.isArray
-nativeKeys = Object.keys |
Create a safe reference to the Underscore object for use below. | _ = (obj) -> new wrapper(obj) |
Export the Underscore object for CommonJS. | if typeof(exports) != 'undefined' then exports._ = _ |
Export Underscore to global scope. | root._ = _ |
Current version. | _.VERSION = '1.1.0' |
Collection Functions | |
The cornerstone, an each implementation. -Handles objects implementing forEach, arrays, and raw objects. | _.each = (obj, iterator, context) ->
- try
- if nativeForEach and obj.forEach is nativeForEach
- obj.forEach iterator, context
- else if _.isNumber obj.length
- iterator.call context, obj[i], i, obj for i in [0...obj.length]
- else
- iterator.call context, val, key, obj for own key, val of obj
- catch e
- throw e if e isnt breaker
- obj |
Return the results of applying the iterator to each element. Use JavaScript -1.6's version of map, if possible. | _.map = (obj, iterator, context) ->
- return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
- results = []
- _.each obj, (value, index, list) ->
- results.push iterator.call context, value, index, list
- results |
Reduce builds up a single result from a list of values. Also known as -inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible. | _.reduce = (obj, iterator, memo, context) ->
- if nativeReduce and obj.reduce is nativeReduce
- iterator = _.bind iterator, context if context
- return obj.reduce iterator, memo
- _.each obj, (value, index, list) ->
- memo = iterator.call context, memo, value, index, list
- memo |
The right-associative version of reduce, also known as foldr. Uses -JavaScript 1.8's version of reduceRight, if available. | _.reduceRight = (obj, iterator, memo, context) ->
- if nativeReduceRight and obj.reduceRight is nativeReduceRight
- iterator = _.bind iterator, context if context
- return obj.reduceRight iterator, memo
- reversed = _.clone(_.toArray(obj)).reverse()
- _.reduce reversed, iterator, memo, context |
Return the first value which passes a truth test. | _.detect = (obj, iterator, context) ->
- result = null
- _.each obj, (value, index, list) ->
- if iterator.call context, value, index, list
- result = value
- _.breakLoop()
- result |
Return all the elements that pass a truth test. Use JavaScript 1.6's -filter, if it exists. | _.filter = (obj, iterator, context) ->
- return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
- results = []
- _.each obj, (value, index, list) ->
- results.push value if iterator.call context, value, index, list
- results |
Return all the elements for which a truth test fails. | _.reject = (obj, iterator, context) ->
- results = []
- _.each obj, (value, index, list) ->
- results.push value if not iterator.call context, value, index, list
- results |
Determine whether all of the elements match a truth test. Delegate to -JavaScript 1.6's every, if it is present. | _.every = (obj, iterator, context) ->
- iterator ||= _.identity
- return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
- result = true
- _.each obj, (value, index, list) ->
- _.breakLoop() unless (result = result and iterator.call(context, value, index, list))
- result |
Determine if at least one element in the object matches a truth test. Use -JavaScript 1.6's some, if it exists. | _.some = (obj, iterator, context) ->
- iterator ||= _.identity
- return obj.some iterator, context if nativeSome and obj.some is nativeSome
- result = false
- _.each obj, (value, index, list) ->
- _.breakLoop() if (result = iterator.call(context, value, index, list))
- result |
Determine if a given value is included in the array or object,
-based on | _.include = (obj, target) ->
- return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
- return true for own key, val of obj when val is target
- false |
Invoke a method with arguments on every item in a collection. | _.invoke = (obj, method) ->
- args = _.rest arguments, 2
- (if method then val[method] else val).apply(val, args) for val in obj |
Convenience version of a common use case of map: fetching a property. | _.pluck = (obj, key) ->
- _.map(obj, (val) -> val[key]) |
Return the maximum item or (item-based computation). | _.max = (obj, iterator, context) ->
- return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
- result = computed: -Infinity
- _.each obj, (value, index, list) ->
- computed = if iterator then iterator.call(context, value, index, list) else value
- computed >= result.computed and (result = {value: value, computed: computed})
- result.value |
Return the minimum element (or element-based computation). | _.min = (obj, iterator, context) ->
- return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
- result = computed: Infinity
- _.each obj, (value, index, list) ->
- computed = if iterator then iterator.call(context, value, index, list) else value
- computed < result.computed and (result = {value: value, computed: computed})
- result.value |
Sort the object's values by a criterion produced by an iterator. | _.sortBy = (obj, iterator, context) ->
- _.pluck(((_.map obj, (value, index, list) ->
- {value: value, criteria: iterator.call(context, value, index, list)}
- ).sort((left, right) ->
- a = left.criteria; b = right.criteria
- if a < b then -1 else if a > b then 1 else 0
- )), 'value') |
Use a comparator function to figure out at what index an object should -be inserted so as to maintain order. Uses binary search. | _.sortedIndex = (array, obj, iterator) ->
- iterator ||= _.identity
- low = 0
- high = array.length
- while low < high
- mid = (low + high) >> 1
- if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
- low |
Convert anything iterable into a real, live array. | _.toArray = (iterable) ->
- return [] if (!iterable)
- return iterable.toArray() if (iterable.toArray)
- return iterable if (_.isArray(iterable))
- return slice.call(iterable) if (_.isArguments(iterable))
- _.values(iterable) |
Return the number of elements in an object. | _.size = (obj) -> _.toArray(obj).length |
Array Functions | |
Get the first element of an array. Passing Baseline setup+ + + + + + +
+
+
+
+
+ ¶
+
+ Establish the root object, root = this
+
+
+
+
+ ¶
+
+ Save the previous value of the previousUnderscore = root._
+
+
+
+
+ ¶
+
+ Establish the object that gets thrown to break out of a loop iteration.
+ breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
+
+
+
+
+ ¶
+
+ Helper function to escape RegExp contents, because JS doesn't have one. + +escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
+
+
+
+
+ ¶
+
+ Save bytes in the minified (but not gzipped) version: + +ArrayProto = Array.prototype
+ObjProto = Object.prototype
+
+
+
+
+ ¶
+
+ Create quick reference variables for speed access to core prototypes. + +slice = ArrayProto.slice
+unshift = ArrayProto.unshift
+toString = ObjProto.toString
+hasOwnProperty = ObjProto.hasOwnProperty
+propertyIsEnumerable = ObjProto.propertyIsEnumerable
+
+
+
+
+ ¶
+
+ All ECMA5 native implementations we hope to use are declared here. + +nativeForEach = ArrayProto.forEach
+nativeMap = ArrayProto.map
+nativeReduce = ArrayProto.reduce
+nativeReduceRight = ArrayProto.reduceRight
+nativeFilter = ArrayProto.filter
+nativeEvery = ArrayProto.every
+nativeSome = ArrayProto.some
+nativeIndexOf = ArrayProto.indexOf
+nativeLastIndexOf = ArrayProto.lastIndexOf
+nativeIsArray = Array.isArray
+nativeKeys = Object.keys
+
+
+
+
+ ¶
+
+ Create a safe reference to the Underscore object for use below. + +_ = (obj) -> new wrapper(obj)
+
+
+
+
+ ¶
+
+ Export the Underscore object for CommonJS. + +if typeof(exports) != 'undefined' then exports._ = _
+
+
+
+
+ ¶
+
+ Export Underscore to global scope. + +root._ = _
+
+
+
+
+ ¶
+
+ Current version. + +_.VERSION = '1.1.0'
+
+
+
+
+ ¶
+
+ Collection Functions+ +
+
+
+
+
+ ¶
+
+ The cornerstone, an each implementation. +Handles objects implementing forEach, arrays, and raw objects. + +_.each = (obj, iterator, context) ->
+ try
+ if nativeForEach and obj.forEach is nativeForEach
+ obj.forEach iterator, context
+ else if _.isNumber obj.length
+ iterator.call context, obj[i], i, obj for i in [0...obj.length]
+ else
+ iterator.call context, val, key, obj for own key, val of obj
+ catch e
+ throw e if e isnt breaker
+ obj
+
+
+
+
+ ¶
+
+ Return the results of applying the iterator to each element. Use JavaScript +1.6's version of map, if possible. + +_.map = (obj, iterator, context) ->
+ return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
+ results = []
+ _.each obj, (value, index, list) ->
+ results.push iterator.call context, value, index, list
+ results
+
+
+
+
+ ¶
+
+ Reduce builds up a single result from a list of values. Also known as +inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible. + +_.reduce = (obj, iterator, memo, context) ->
+ if nativeReduce and obj.reduce is nativeReduce
+ iterator = _.bind iterator, context if context
+ return obj.reduce iterator, memo
+ _.each obj, (value, index, list) ->
+ memo = iterator.call context, memo, value, index, list
+ memo
+
+
+
+
+ ¶
+
+ The right-associative version of reduce, also known as foldr. Uses +JavaScript 1.8's version of reduceRight, if available. + +_.reduceRight = (obj, iterator, memo, context) ->
+ if nativeReduceRight and obj.reduceRight is nativeReduceRight
+ iterator = _.bind iterator, context if context
+ return obj.reduceRight iterator, memo
+ reversed = _.clone(_.toArray(obj)).reverse()
+ _.reduce reversed, iterator, memo, context
+
+
+
+
+ ¶
+
+ Return the first value which passes a truth test. + +_.detect = (obj, iterator, context) ->
+ result = null
+ _.each obj, (value, index, list) ->
+ if iterator.call context, value, index, list
+ result = value
+ _.breakLoop()
+ result
+
+
+
+
+ ¶
+
+ Return all the elements that pass a truth test. Use JavaScript 1.6's +filter, if it exists. + +_.filter = (obj, iterator, context) ->
+ return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
+ results = []
+ _.each obj, (value, index, list) ->
+ results.push value if iterator.call context, value, index, list
+ results
+
+
+
+
+ ¶
+
+ Return all the elements for which a truth test fails. + +_.reject = (obj, iterator, context) ->
+ results = []
+ _.each obj, (value, index, list) ->
+ results.push value if not iterator.call context, value, index, list
+ results
+
+
+
+
+ ¶
+
+ Determine whether all of the elements match a truth test. Delegate to +JavaScript 1.6's every, if it is present. + +_.every = (obj, iterator, context) ->
+ iterator ||= _.identity
+ return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
+ result = true
+ _.each obj, (value, index, list) ->
+ _.breakLoop() unless (result = result and iterator.call(context, value, index, list))
+ result
+
+
+
+
+ ¶
+
+ Determine if at least one element in the object matches a truth test. Use +JavaScript 1.6's some, if it exists. + +_.some = (obj, iterator, context) ->
+ iterator ||= _.identity
+ return obj.some iterator, context if nativeSome and obj.some is nativeSome
+ result = false
+ _.each obj, (value, index, list) ->
+ _.breakLoop() if (result = iterator.call(context, value, index, list))
+ result
+
+
+
+
+ ¶
+
+ Determine if a given value is included in the array or object,
+based on _.include = (obj, target) ->
+ return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
+ return true for own key, val of obj when val is target
+ false
+
+
+
+
+ ¶
+
+ Invoke a method with arguments on every item in a collection. + +_.invoke = (obj, method) ->
+ args = _.rest arguments, 2
+ (if method then val[method] else val).apply(val, args) for val in obj
+
+
+
+
+ ¶
+
+ Convenience version of a common use case of map: fetching a property. + +_.pluck = (obj, key) ->
+ _.map(obj, (val) -> val[key])
+
+
+
+
+ ¶
+
+ Return the maximum item or (item-based computation). + +_.max = (obj, iterator, context) ->
+ return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
+ result = computed: -Infinity
+ _.each obj, (value, index, list) ->
+ computed = if iterator then iterator.call(context, value, index, list) else value
+ computed >= result.computed and (result = {value: value, computed: computed})
+ result.value
+
+
+
+
+ ¶
+
+ Return the minimum element (or element-based computation). + +_.min = (obj, iterator, context) ->
+ return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
+ result = computed: Infinity
+ _.each obj, (value, index, list) ->
+ computed = if iterator then iterator.call(context, value, index, list) else value
+ computed < result.computed and (result = {value: value, computed: computed})
+ result.value
+
+
+
+
+ ¶
+
+ Sort the object's values by a criterion produced by an iterator. + +_.sortBy = (obj, iterator, context) ->
+ _.pluck(((_.map obj, (value, index, list) ->
+ {value: value, criteria: iterator.call(context, value, index, list)}
+ ).sort((left, right) ->
+ a = left.criteria; b = right.criteria
+ if a < b then -1 else if a > b then 1 else 0
+ )), 'value')
+
+
+
+
+ ¶
+
+ Use a comparator function to figure out at what index an object should +be inserted so as to maintain order. Uses binary search. + +_.sortedIndex = (array, obj, iterator) ->
+ iterator ||= _.identity
+ low = 0
+ high = array.length
+ while low < high
+ mid = (low + high) >> 1
+ if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
+ low
+
+
+
+
+ ¶
+
+ Convert anything iterable into a real, live array. + +_.toArray = (iterable) ->
+ return [] if (!iterable)
+ return iterable.toArray() if (iterable.toArray)
+ return iterable if (_.isArray(iterable))
+ return slice.call(iterable) if (_.isArguments(iterable))
+ _.values(iterable)
+
+
+
+
+ ¶
+
+ Return the number of elements in an object. + +_.size = (obj) -> _.toArray(obj).length
+
+
+
+
+ ¶
+
+ Array Functions+ +
+
+
+ ¶
+
+ Get the first element of an array. Passing | _.first = (array, n, guard) ->
- if n and not guard then slice.call(array, 0, n) else array[0] |
Returns everything but the first entry of the array. Aliased as tail. +with map. + + + +_.first = (array, n, guard) ->
+ if n and not guard then slice.call(array, 0, n) else array[0]
+
+
+ ¶
+
+ Returns everything but the first entry of the array. Aliased as tail.
Especially useful on the arguments object. Passing an | _.rest = (array, index, guard) ->
- slice.call(array, if _.isUndefined(index) or guard then 1 else index) |
Get the last element of an array. | _.last = (array) -> array[array.length - 1] |
Trim out all falsy values from an array. | _.compact = (array) -> item for item in array when item |
Return a completely flattened version of an array. | _.flatten = (array) ->
- _.reduce array, (memo, value) ->
- return memo.concat(_.flatten(value)) if _.isArray value
- memo.push value
- memo
- , [] |
Return a version of the array that does not contain the specified value(s). | _.without = (array) ->
- values = _.rest arguments
- val for val in _.toArray(array) when not _.include values, val |
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 = (array, isSorted) ->
- memo = []
- for el, i in _.toArray array
- memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
- memo |
Produce an array that contains every item shared between all the -passed-in arrays. | _.intersect = (array) ->
- rest = _.rest arguments
- _.select _.uniq(array), (item) ->
- _.all rest, (other) ->
- _.indexOf(other, item) >= 0 |
Zip together multiple lists into a single array -- elements that share -an index go together. | _.zip = ->
- length = _.max _.pluck arguments, 'length'
- results = new Array length
- for i in [0...length]
- results[i] = _.pluck arguments, String i
- results |
If the browser doesn't supply us with indexOf (I'm looking at you, MSIE), +check allows it to work with map. + + + +_.rest = (array, index, guard) ->
+ slice.call(array, if _.isUndefined(index) or guard then 1 else index)
+
+
+
+
+ ¶
+
+ Get the last element of an array. + +_.last = (array) -> array[array.length - 1]
+
+
+
+
+ ¶
+
+ Trim out all falsy values from an array. + +_.compact = (array) -> item for item in array when item
+
+
+
+
+ ¶
+
+ Return a completely flattened version of an array. + +_.flatten = (array) ->
+ _.reduce array, (memo, value) ->
+ return memo.concat(_.flatten(value)) if _.isArray value
+ memo.push value
+ memo
+ , []
+
+
+
+
+ ¶
+
+ Return a version of the array that does not contain the specified value(s). + +_.without = (array) ->
+ values = _.rest arguments
+ val for val in _.toArray(array) when not _.include values, val
+
+
+
+
+ ¶
+
+ 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 = (array, isSorted) ->
+ memo = []
+ for el, i in _.toArray array
+ memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
+ memo
+
+
+
+
+ ¶
+
+ Produce an array that contains every item shared between all the +passed-in arrays. + +_.intersect = (array) ->
+ rest = _.rest arguments
+ _.select _.uniq(array), (item) ->
+ _.all rest, (other) ->
+ _.indexOf(other, item) >= 0
+
+
+
+
+ ¶
+
+ Zip together multiple lists into a single array -- elements that share +an index go together. + +_.zip = ->
+ length = _.max _.pluck arguments, 'length'
+ results = new Array length
+ for i in [0...length]
+ results[i] = _.pluck arguments, String i
+ results
+
+
+ ¶
+
+ If the browser doesn't supply us with indexOf (I'm looking at you, MSIE), we need this function. Return the position of the first occurrence of an -item in an array, or -1 if the item is not included in the array. | _.indexOf = (array, item) ->
- return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
- i = 0; l = array.length
- while l - i
- if array[i] is item then return i else i++
- -1 |
Provide JavaScript 1.6's lastIndexOf, delegating to the native function, -if possible. | _.lastIndexOf = (array, item) ->
- return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
- i = array.length
- while i
- if array[i] is item then return i else i--
- -1 |
Generate an integer Array containing an arithmetic progression. A port of -the native Python range function. | _.range = (start, stop, step) ->
- a = arguments
- solo = a.length <= 1
- i = start = if solo then 0 else a[0]
- stop = if solo then a[0] else a[1]
- step = a[2] or 1
- len = Math.ceil((stop - start) / step)
- return [] if len <= 0
- range = new Array len
- idx = 0
- loop
- return range if (if step > 0 then i - stop else stop - i) >= 0
- range[idx] = i
- idx++
- i+= step |
Function Functions | |
Create a function bound to a given object (assigning | _.bind = (func, obj) ->
- args = _.rest arguments, 2
- -> func.apply obj or root, args.concat arguments |
Bind all of an object's methods to that object. Useful for ensuring that -all callbacks defined on an object belong to it. | _.bindAll = (obj) ->
- funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
- _.each funcs, (f) -> obj[f] = _.bind obj[f], obj
- obj |
Delays a function for the given number of milliseconds, and then calls -it with the arguments supplied. | _.delay = (func, wait) ->
- args = _.rest arguments, 2
- setTimeout((-> func.apply(func, args)), wait) |
Memoize an expensive function by storing its results. | _.memoize = (func, hasher) ->
- memo = {}
- hasher or= _.identity
- ->
- key = hasher.apply this, arguments
- return memo[key] if key of memo
- memo[key] = func.apply this, arguments |
Defers a function, scheduling it to run after the current call stack has -cleared. | _.defer = (func) ->
- _.delay.apply _, [func, 1].concat _.rest arguments |
Returns the first function passed as an argument to the second, +item in an array, or -1 if the item is not included in the array. + + + +_.indexOf = (array, item) ->
+ return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
+ i = 0; l = array.length
+ while l - i
+ if array[i] is item then return i else i++
+ -1
+
+
+
+
+ ¶
+
+ Provide JavaScript 1.6's lastIndexOf, delegating to the native function, +if possible. + +_.lastIndexOf = (array, item) ->
+ return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
+ i = array.length
+ while i
+ if array[i] is item then return i else i--
+ -1
+
+
+
+
+ ¶
+
+ Generate an integer Array containing an arithmetic progression. A port of +the native Python range function. + +_.range = (start, stop, step) ->
+ a = arguments
+ solo = a.length <= 1
+ i = start = if solo then 0 else a[0]
+ stop = if solo then a[0] else a[1]
+ step = a[2] or 1
+ len = Math.ceil((stop - start) / step)
+ return [] if len <= 0
+ range = new Array len
+ idx = 0
+ loop
+ return range if (if step > 0 then i - stop else stop - i) >= 0
+ range[idx] = i
+ idx++
+ i+= step
+
+
+
+
+ ¶
+
+ Function Functions+ +
+
+
+
+
+ ¶
+
+ Create a function bound to a given object (assigning _.bind = (func, obj) ->
+ args = _.rest arguments, 2
+ -> func.apply obj or root, args.concat arguments
+
+
+
+
+ ¶
+
+ Bind all of an object's methods to that object. Useful for ensuring that +all callbacks defined on an object belong to it. + +_.bindAll = (obj) ->
+ funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
+ _.each funcs, (f) -> obj[f] = _.bind obj[f], obj
+ obj
+
+
+
+
+ ¶
+
+ Delays a function for the given number of milliseconds, and then calls +it with the arguments supplied. + +_.delay = (func, wait) ->
+ args = _.rest arguments, 2
+ setTimeout((-> func.apply(func, args)), wait)
+
+
+
+
+ ¶
+
+ Memoize an expensive function by storing its results. + +_.memoize = (func, hasher) ->
+ memo = {}
+ hasher or= _.identity
+ ->
+ key = hasher.apply this, arguments
+ return memo[key] if key of memo
+ memo[key] = func.apply this, arguments
+
+
+
+
+ ¶
+
+ Defers a function, scheduling it to run after the current call stack has +cleared. + +_.defer = (func) ->
+ _.delay.apply _, [func, 1].concat _.rest arguments
+
+
+ ¶
+
+ Returns the first function passed as an argument to the second, allowing you to adjust arguments, run code before and after, and -conditionally execute the original function. | _.wrap = (func, wrapper) ->
- -> wrapper.apply wrapper, [func].concat arguments |
Returns a function that is the composition of a list of functions, each -consuming the return value of the function that follows. | _.compose = ->
- funcs = arguments
- ->
- args = arguments
- for i in [funcs.length - 1..0] by -1
- args = [funcs[i].apply(this, args)]
- args[0] |
Object Functions | |
Retrieve the names of an object's properties. | _.keys = nativeKeys or (obj) ->
- return _.range 0, obj.length if _.isArray(obj)
- key for key, val of obj |
Retrieve the values of an object's properties. | _.values = (obj) ->
- _.map obj, _.identity |
Return a sorted list of the function names available in Underscore. | _.functions = (obj) ->
- _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort() |
Extend a given object with all of the properties in a source object. | _.extend = (obj) ->
- for source in _.rest(arguments)
- obj[key] = val for key, val of source
- obj |
Create a (shallow-cloned) duplicate of an object. | _.clone = (obj) ->
- return obj.slice 0 if _.isArray obj
- _.extend {}, obj |
Invokes interceptor with the obj, and then returns obj. -The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. | _.tap = (obj, interceptor) ->
- interceptor obj
- obj |
Perform a deep comparison to check if two objects are equal. | _.isEqual = (a, b) -> |
Check object identity. | return true if a is b |
Different types? | atype = typeof(a); btype = typeof(b)
- return false if atype isnt btype |
Basic equality test (watch out for coercions). | return true if `a == b` |
One is falsy and the other truthy. | return false if (!a and b) or (a and !b) |
One of them implements an | return a.isEqual(b) if a.isEqual |
Check dates' integer values. | return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b) |
Both are NaN? | return false if _.isNaN(a) and _.isNaN(b) |
Compare regular expressions. | if _.isRegExp(a) and _.isRegExp(b)
- return a.source is b.source and
- a.global is b.global and
- a.ignoreCase is b.ignoreCase and
- a.multiline is b.multiline |
If a is not an object by this point, we can't handle it. | return false if atype isnt 'object' |
Check for different array lengths before comparing contents. | return false if a.length and (a.length isnt b.length) |
Nothing else worked, deep compare the contents. | aKeys = _.keys(a); bKeys = _.keys(b) |
Different object sizes? | return false if aKeys.length isnt bKeys.length |
Recursive comparison of contents. | return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
- true |
Is a given array or object empty? | _.isEmpty = (obj) ->
- return obj.length is 0 if _.isArray(obj) or _.isString(obj)
- return false for own key of obj
- true |
Is a given value a DOM element? | _.isElement = (obj) -> obj and obj.nodeType is 1 |
Is a given value an array? | _.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee) |
Is a given variable an arguments object? | _.isArguments = (obj) -> obj and obj.callee |
Is the given value a function? | _.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply) |
Is the given value a string? | _.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr)) |
Is a given value a number? | _.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]' |
Is a given value a boolean? | _.isBoolean = (obj) -> obj is true or obj is false |
Is a given value a Date? | _.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear) |
Is the given value a regular expression? | _.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false)) |
Is the given value NaN -- this one is interesting. | _.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj) |
Is a given value equal to null? | _.isNull = (obj) -> obj is null |
Is a given variable undefined? | _.isUndefined = (obj) -> typeof obj is 'undefined' |
Utility Functions | |
Run Underscore.js in noConflict mode, returning the | _.noConflict = ->
- root._ = previousUnderscore
- this |
Keep the identity function around for default iterators. | _.identity = (value) -> value |
Run a function | _.times = (n, iterator, context) ->
- iterator.call context, i for i in [0...n] |
Break out of the middle of an iteration. | _.breakLoop = -> throw breaker |
Add your own custom functions to the Underscore object, ensuring that -they're correctly added to the OOP wrapper as well. | _.mixin = (obj) ->
- for name in _.functions(obj)
- addToWrapper name, _[name] = obj[name] |
Generate a unique integer id (unique within the entire client session). -Useful for temporary DOM ids. | idCounter = 0
-_.uniqueId = (prefix) ->
- (prefix or '') + idCounter++ |
By default, Underscore uses ERB-style template delimiters, change the -following template settings to use alternative delimiters. | _.templateSettings = {
- start: '<%'
- end: '%>'
- interpolate: /<%=(.+?)%>/g
-} |
JavaScript templating a-la ERB, pilfered from John Resig's +conditionally execute the original function. + + + +_.wrap = (func, wrapper) ->
+ -> wrapper.apply wrapper, [func].concat arguments
+
+
+
+
+ ¶
+
+ Returns a function that is the composition of a list of functions, each +consuming the return value of the function that follows. + +_.compose = ->
+ funcs = arguments
+ ->
+ args = arguments
+ for i in [funcs.length - 1..0] by -1
+ args = [funcs[i].apply(this, args)]
+ args[0]
+
+
+
+
+ ¶
+
+ Object Functions+ +
+
+
+
+
+ ¶
+
+ Retrieve the names of an object's properties. + +_.keys = nativeKeys or (obj) ->
+ return _.range 0, obj.length if _.isArray(obj)
+ key for key, val of obj
+
+
+
+
+ ¶
+
+ Retrieve the values of an object's properties. + +_.values = (obj) ->
+ _.map obj, _.identity
+
+
+
+
+ ¶
+
+ Return a sorted list of the function names available in Underscore. + +_.functions = (obj) ->
+ _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
+
+
+
+
+ ¶
+
+ Extend a given object with all of the properties in a source object. + +_.extend = (obj) ->
+ for source in _.rest(arguments)
+ obj[key] = val for key, val of source
+ obj
+
+
+
+
+ ¶
+
+ Create a (shallow-cloned) duplicate of an object. + +_.clone = (obj) ->
+ return obj.slice 0 if _.isArray obj
+ _.extend {}, obj
+
+
+
+
+ ¶
+
+ Invokes interceptor with the obj, and then returns obj. +The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. + +_.tap = (obj, interceptor) ->
+ interceptor obj
+ obj
+
+
+
+
+ ¶
+
+ Perform a deep comparison to check if two objects are equal. + +_.isEqual = (a, b) ->
+
+
+
+
+ ¶
+
+ Check object identity. + + return true if a is b
+
+
+
+
+ ¶
+
+ Different types? + + atype = typeof(a); btype = typeof(b)
+ return false if atype isnt btype
+
+
+
+
+ ¶
+
+ Basic equality test (watch out for coercions). + + return true if `a == b`
+
+
+
+
+ ¶
+
+ One is falsy and the other truthy. + + return false if (!a and b) or (a and !b)
+
+
+
+
+ ¶
+
+ One of them implements an return a.isEqual(b) if a.isEqual
+
+
+
+
+ ¶
+
+ Check dates' integer values. + + return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
+
+
+
+
+ ¶
+
+ Both are NaN? + + return false if _.isNaN(a) and _.isNaN(b)
+
+
+
+
+ ¶
+
+ Compare regular expressions. + + if _.isRegExp(a) and _.isRegExp(b)
+ return a.source is b.source and
+ a.global is b.global and
+ a.ignoreCase is b.ignoreCase and
+ a.multiline is b.multiline
+
+
+
+
+ ¶
+
+ If a is not an object by this point, we can't handle it. + + return false if atype isnt 'object'
+
+
+
+
+ ¶
+
+ Check for different array lengths before comparing contents. + + return false if a.length and (a.length isnt b.length)
+
+
+
+
+ ¶
+
+ Nothing else worked, deep compare the contents. + + aKeys = _.keys(a); bKeys = _.keys(b)
+
+
+
+
+ ¶
+
+ Different object sizes? + + return false if aKeys.length isnt bKeys.length
+
+
+
+
+ ¶
+
+ Recursive comparison of contents. + + return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
+ true
+
+
+
+
+ ¶
+
+ Is a given array or object empty? + +_.isEmpty = (obj) ->
+ return obj.length is 0 if _.isArray(obj) or _.isString(obj)
+ return false for own key of obj
+ true
+
+
+
+
+ ¶
+
+ Is a given value a DOM element? + +_.isElement = (obj) -> obj and obj.nodeType is 1
+
+
+
+
+ ¶
+
+ Is a given value an array? + +_.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
+
+
+
+
+ ¶
+
+ Is a given variable an arguments object? + +_.isArguments = (obj) -> obj and obj.callee
+
+
+
+
+ ¶
+
+ Is the given value a function? + +_.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
+
+
+
+
+ ¶
+
+ Is the given value a string? + +_.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
+
+
+
+
+ ¶
+
+ Is a given value a number? + +_.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
+
+
+
+
+ ¶
+
+ Is a given value a boolean? + +_.isBoolean = (obj) -> obj is true or obj is false
+
+
+
+
+ ¶
+
+ Is a given value a Date? + +_.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
+
+
+
+
+ ¶
+
+ Is the given value a regular expression? + +_.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
+
+
+
+
+ ¶
+
+ Is the given value NaN -- this one is interesting. _.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj)
+
+
+
+
+ ¶
+
+ Is a given value equal to null? + +_.isNull = (obj) -> obj is null
+
+
+
+
+ ¶
+
+ Is a given variable undefined? + +_.isUndefined = (obj) -> typeof obj is 'undefined'
+
+
+
+
+ ¶
+
+ Utility Functions+ +
+
+
+
+
+ ¶
+
+ Run Underscore.js in noConflict mode, returning the _.noConflict = ->
+ root._ = previousUnderscore
+ this
+
+
+
+
+ ¶
+
+ Keep the identity function around for default iterators. + +_.identity = (value) -> value
+
+
+
+
+ ¶
+
+ Run a function _.times = (n, iterator, context) ->
+ iterator.call context, i for i in [0...n]
+
+
+
+
+ ¶
+
+ Break out of the middle of an iteration. + +_.breakLoop = -> throw breaker
+
+
+
+
+ ¶
+
+ Add your own custom functions to the Underscore object, ensuring that +they're correctly added to the OOP wrapper as well. + +_.mixin = (obj) ->
+ for name in _.functions(obj)
+ addToWrapper name, _[name] = obj[name]
+
+
+
+
+ ¶
+
+ Generate a unique integer id (unique within the entire client session). +Useful for temporary DOM ids. + +idCounter = 0
+_.uniqueId = (prefix) ->
+ (prefix or '') + idCounter++
+
+
+
+
+ ¶
+
+ By default, Underscore uses ERB-style template delimiters, change the +following template settings to use alternative delimiters. + +_.templateSettings = {
+ start: '<%'
+ end: '%>'
+ interpolate: /<%=(.+?)%>/g
+}
+
+
+ ¶
+
+ JavaScript templating a-la ERB, pilfered from John Resig's Secrets of the JavaScript Ninja, page 83. Single-quote fix from Rick Strahl. -With alterations for arbitrary delimiters, and to preserve whitespace. | _.template = (str, data) ->
- c = _.templateSettings
- endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
- fn = new Function 'obj',
- 'var p=[],print=function(){p.push.apply(p,arguments);};' +
- 'with(obj||{}){p.push(\'' +
- str.replace(/\r/g, '\\r')
- .replace(/\n/g, '\\n')
- .replace(/\t/g, '\\t')
- .replace(endMatch,"✄")
- .split("'").join("\\'")
- .split("✄").join("'")
- .replace(c.interpolate, "',$1,'")
- .split(c.start).join("');")
- .split(c.end).join("p.push('") +
- "');}return p.join('');"
- if data then fn(data) else fn |
Aliases | _.forEach = _.each
-_.foldl = _.inject = _.reduce
-_.foldr = _.reduceRight
-_.select = _.filter
-_.all = _.every
-_.any = _.some
-_.contains = _.include
-_.head = _.first
-_.tail = _.rest
-_.methods = _.functions |
Setup the OOP Wrapper | |
If Underscore is called as a function, it returns a wrapped object that -can be used OO-style. This wrapper holds altered versions of all the -underscore functions. Wrapped objects may be chained. | wrapper = (obj) ->
- this._wrapped = obj
- this |
Helper function to continue chaining intermediate results. | result = (obj, chain) ->
- if chain then _(obj).chain() else obj |
A method to easily add functions to the OOP wrapper. | addToWrapper = (name, func) ->
- wrapper.prototype[name] = ->
- args = _.toArray arguments
- unshift.call args, this._wrapped
- result func.apply(_, args), this._chain |
Add all ofthe Underscore functions to the wrapper object. | _.mixin _ |
Add all mutator Array functions to the wrapper. | _.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
- method = Array.prototype[name]
- wrapper.prototype[name] = ->
- method.apply(this._wrapped, arguments)
- result(this._wrapped, this._chain) |
Add all accessor Array functions to the wrapper. | _.each ['concat', 'join', 'slice'], (name) ->
- method = Array.prototype[name]
- wrapper.prototype[name] = ->
- result(method.apply(this._wrapped, arguments), this._chain) |
Start chaining a wrapped Underscore object. | wrapper::chain = ->
- this._chain = true
- this |
Extracts the result from a wrapped and chained object. | wrapper::value = -> this._wrapped
+With alterations for arbitrary delimiters, and to preserve whitespace.
- |
_.template = (str, data) ->
+ c = _.templateSettings
+ endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
+ fn = new Function 'obj',
+ 'var p=[],print=function(){p.push.apply(p,arguments);};' +
+ 'with(obj||{}){p.push(\'' +
+ str.replace(/\r/g, '\\r')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ .replace(endMatch,"✄")
+ .split("'").join("\\'")
+ .split("✄").join("'")
+ .replace(c.interpolate, "',$1,'")
+ .split(c.start).join("');")
+ .split(c.end).join("p.push('") +
+ "');}return p.join('');"
+ if data then fn(data) else fn
_.forEach = _.each
+_.foldl = _.inject = _.reduce
+_.foldr = _.reduceRight
+_.select = _.filter
+_.all = _.every
+_.any = _.some
+_.contains = _.include
+_.head = _.first
+_.tail = _.rest
+_.methods = _.functions
If Underscore is called as a function, it returns a wrapped object that +can be used OO-style. This wrapper holds altered versions of all the +underscore functions. Wrapped objects may be chained.
+ +wrapper = (obj) ->
+ this._wrapped = obj
+ this
Helper function to continue chaining intermediate results.
+ +result = (obj, chain) ->
+ if chain then _(obj).chain() else obj
A method to easily add functions to the OOP wrapper.
+ +addToWrapper = (name, func) ->
+ wrapper.prototype[name] = ->
+ args = _.toArray arguments
+ unshift.call args, this._wrapped
+ result func.apply(_, args), this._chain
Add all ofthe Underscore functions to the wrapper object.
+ +_.mixin _
Add all mutator Array functions to the wrapper.
+ +_.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
+ method = Array.prototype[name]
+ wrapper.prototype[name] = ->
+ method.apply(this._wrapped, arguments)
+ result(this._wrapped, this._chain)
Add all accessor Array functions to the wrapper.
+ +_.each ['concat', 'join', 'slice'], (name) ->
+ method = Array.prototype[name]
+ wrapper.prototype[name] = ->
+ result(method.apply(this._wrapped, arguments), this._chain)
Start chaining a wrapped Underscore object.
+ +wrapper::chain = ->
+ this._chain = true
+ this
Extracts the result from a wrapped and chained object.
+ +wrapper::value = -> this._wrapped