Share
Embed
Underscore.js - Overview of functions, Part II: Functions, Objects, and Utilities
Sidnet
June 30, 2015
Transcript
126 slides
-
Underscore.js Overview of functions Part II: Functions, Objects, and Utilities
Marcin Tabaka June 30, 2015 -
Outline Part I: • Introduction • Collections • Arrays Part
II: • Functions • Objects • Utilities • Summary -
Function Functions (yeah, I know) after once before partial bind
throttle bindAll wrap compose debounce defer delay memoize negate -
bind Underscore.js docs: Bind a function to an object, meaning
that whenever the function is called, the value of this will be the object. Optionally, pass arguments to the function to pre-fill them, also known as partial application. For partial application without context binding, use partial. -
bind var func = function (label) { return label +
': ' + this.number; }; func = _.bind(func, { number: 42 }, 'ID'); func(); -
bind var func = function (label) { return label +
': ' + this.number; }; func = _.bind(func, { number: 42 }, 'ID'); func(); // => 'ID: 42' -
bindAll Underscore.js docs: Binds a number of methods on the
object, specified by methodNames, to be run in the context of that object whenever they are invoked. Very handy for binding functions that are going to be used as event handlers, which would otherwise be invoked with a fairly useless this. methodNames are required. -
bindAll var inputView = { label: 'Name', change: function ()
{ console.log(this.label + ' changed'); }, focus: function () { console.log(this.label + ' focused'); } }; _.bindAll(inputView, 'onChange', 'onFocus'); $('#name').bind('change', inputView.change); -
partial Underscore.js docs: Partially apply a function by filling in
any number of its arguments, without changing its dynamic this value. A close cousin of bind. You may pass _ in your list of arguments to specify an argument that should not be pre-filled, but left open to supply at call-time. -
partial var url = function(host, path) { return 'http://' +
host + '/' + path; }; twitterUrl = _.partial(url, 'twitter.com'); twitterUrl('sidnet_en'); -
partial var url = function(host, path) { return 'http://' +
host + '/' + path; }; twitterUrl = _.partial(url, 'twitter.com'); twitterUrl('sidnet_en'); // => 'http://twitter.com/sidnet_en' -
partial var url = function(host, path) { return 'http://' +
host + '/' + path; }; twitterUrl = _.partial(url, 'twitter.com'); twitterUrl('sidnet_en'); // => 'http://twitter.com/sidnet_en' indexUrl = _.partial(url, _, 'index.html'); indexUrl('www.w3.org'); -
partial var url = function(host, path) { return 'http://' +
host + '/' + path; }; twitterUrl = _.partial(url, 'twitter.com'); twitterUrl('sidnet_en'); // => 'http://twitter.com/sidnet_en' indexUrl = _.partial(url, _, 'index.html'); indexUrl('www.w3.org'); // => 'http://www.w3.org/index.html' -
memoize Underscore.js docs: Memoizes a given function by caching the
result. Useful for speeding up slow-running computations. If passed an optional hashFunction, it will be used to compute the hash key for storing the result, based on the arguments. The default hashFunction uses the first argument to the memoized function as the key. -
memoize var fib = _.memoize(function(n) { return n < 2
? n: fib(n-1) + fib(n-2); }); -
delay Underscore.js docs: Much like setTimeout, invokes function after wait
milliseconds. If you pass the optional arguments, they will be forwarded on to the function when it is invoked. -
defer Underscore.js docs: Defers invoking the function until the current
call stack has cleared, similar to using setTimeout with a delay of 0. Useful for performing expensive computations or HTML rendering in chunks without blocking the UI thread. If you pass the optional arguments, they will be forwarded on to the function when it is invoked. -
throttle Underscore.js docs: Creates and returns a new, throttled version
of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds. Useful for rate- limiting events that occur faster than you can keep up with. -
debounce Underscore.js docs: Creates and returns a new debounced version
of the passed function which will postpone its execution until after wait milliseconds have elapsed since the last time it was invoked. Useful for implementing behavior that should only happen after the input has stopped arriving. -
once Underscore.js docs: Creates a version of the function that
can only be called one time. Repeated calls to the modified function will have no effect, returning the value from the original call. Useful for initialization functions, instead of having to set a boolean flag and then check it later. -
after Underscore.js docs: Creates a version of the function that
will only be run after first being called count times. Useful for grouping asynchronous responses, where you want to be sure that all the async calls have finished, before proceeding. -
after var callMe = _.after(3, function () { return "Third
time's the charm"; }); callMe(); callMe(); callMe(); -
after var callMe = _.after(3, function () { return "Third
time's the charm"; }); callMe(); // => undefined callMe(); callMe(); -
after var callMe = _.after(3, function () { return "Third
time's the charm"; }); callMe(); // => undefined callMe(); // => undefined callMe(); -
after var callMe = _.after(3, function () { return "Third
time's the charm"; }); callMe(); // => undefined callMe(); // => undefined callMe(); // => "Third time's the charm" -
after var updateItems = _.after( items.length, doUpdate ); _.each(items, function
(item) { item.asyncSave().done(function () { // Will be only run once, after all // items are saved updateItems(); }); }); -
before Underscore.js docs: Creates a version of the function that
can be called no more than count times. The result of the last function call is memoized and returned when count has been reached. -
before var counter = 0; var callMeTwice = _.before(3, function
() { return ++counter; }); callMeTwice(); callMeTwice(); callMeTwice(); -
before var counter = 0; var callMeTwice = _.before(3, function
() { return ++counter; }); callMeTwice(); // => 1 callMeTwice(); callMeTwice(); -
before var counter = 0; var callMeTwice = _.before(3, function
() { return ++counter; }); callMeTwice(); // => 1 callMeTwice(); // => 2 callMeTwice(); -
before var counter = 0; var callMeTwice = _.before(3, function
() { return ++counter; }); callMeTwice(); // => 1 callMeTwice(); // => 2 callMeTwice(); // => 2 (memoized) -
wrap Underscore.js docs: Wraps the first function inside of the
wrapper function, passing it as the first argument. This allows the wrapper to execute code before and after the function runs, adjust the arguments, and execute it conditionally. -
wrap var hello = function(name) { return "Hello " +
name; }; var helloUpper = _.wrap( hello, function (func, name) { return func(name).toUpperCase(); } ); hello("Bob"); helloUpper("Bob"); -
wrap var hello = function(name) { return "Hello " +
name; }; var helloUpper = _.wrap( hello, function (func, name) { return func(name).toUpperCase(); } ); hello("Bob"); // => "Hello Bob" helloUpper("Bob"); -
wrap var hello = function(name) { return "Hello " +
name; }; var helloUpper = _.wrap( hello, function (func, name) { return func(name).toUpperCase(); } ); hello("Bob"); // => "Hello Bob" helloUpper("Bob"); // => "HELLO BOB" -
Object Functions allKeys functions omit clone has pairs create invert
pick defaults is* property extend keys propertyOf extendOwn mapObject tap findKey matcher values -
keys / allKeys Underscore.js docs: keys() - Retrieve all the
names of the object's own enumerable properties. allKeys() - Retrieve all the names of object's own and inherited properties. -
keys / allKeys function Book(title) { this.title = title; }
Book.prototype.format = "hardcover"; var b = new Book("Ulysses"); _.keys(b); _.allKeys(b); -
keys / allKeys function Book(title) { this.title = title; }
Book.prototype.format = "hardcover"; var b = new Book("Ulysses"); _.keys(b); // => ["title"] _.allKeys(b); -
keys / allKeys function Book(title) { this.title = title; }
Book.prototype.format = "hardcover"; var b = new Book("Ulysses"); _.keys(b); // => ["title"] _.allKeys(b); // => ["title", "format"] -
values Underscore.js docs: Return all of the values of the
object's own properties. -
values function Book(title) { this.title = title; } Book.prototype.format =
"hardcover"; var b = new Book("Ulysses"); _.values(b); -
values function Book(title) { this.title = title; } Book.prototype.format =
"hardcover"; var b = new Book("Ulysses"); _.values(b); // => ["Ulysses"] -
mapObject Underscore.js docs: Like map, but for objects. Transform the
value of each property in turn. -
mapObject var obj = { foo: 4, bar: 8 };
_.mapObject(obj, function (val, key) { return val * 2; }); -
mapObject var obj = { foo: 4, bar: 8 };
_.mapObject(obj, function (val, key) { return val * 2; }); // => { foo: 8, bar: 16 } -
pairs Underscore.js docs: Convert an object into a list of
[key, value] pairs. -
pairs _.pairs({ foo: 42, bar: "baz" }); // => [["foo",
1], ["bar", "baz"]] -
create Underscore.js docs: Creates a new object with the given
prototype, optionally attaching props as own properties. Basically, Object.create, but without all of the property descriptor jazz. -
functions Underscore.js docs: Returns a sorted list of the names
of every method in an object — that is to say, the name of every function property of the object. -
functions _.functions(window); // => [ "_", "addEventListener", "alert", // =>
"atob", "blur", ... ] -
findKey Underscore.js docs: Similar to _.findIndex but for keys in
objects. Returns the key where the predicate truth test passes or undefined. -
findKey var obj = { foo: 5, bar: 15 };
_.findKey(obj, function (val, key) { return val > 10; }); -
findKey var obj = { foo: 5, bar: 15 };
_.findKey(obj, function (val, key) { return val > 10; }); // => "bar" -
clone Underscore.js docs: Create a shallow-copied clone of the provided
plain object. Any nested objects or arrays will be copied by reference, not duplicated. -
clone _.clone({ title: 'Crime and Punishment'}); // => { title:
'Crime and Punishment' } -
extend / extendOwn Underscore.js docs: extend() - Copy all of
the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments. extendOwn() - Just like extend(), but copies only own properties of supplied objects. -
extend / extendOwn function Book(title) { this.title = title; }
Book.prototype.format = "hardcover"; var b1 = _.extend({}, new Book()); b1.format; var b2 = _.extendOwn({}, new Book()); b2.format; -
extend / extendOwn function Book(title) { this.title = title; }
Book.prototype.format = "hardcover"; var b1 = _.extend({}, new Book()); b1.format; // => "hardcover" var b2 = _.extendOwn({}, new Book()); b2.format; -
extend / extendOwn function Book(title) { this.title = title; }
Book.prototype.format = "hardcover"; var b1 = _.extend({}, new Book()); b1.format; // => "hardcover" var b2 = _.extendOwn({}, new Book()); b2.format; // => undefined -
pick Underscore.js docs: Return a copy of the object, filtered
to only have values for the whitelisted keys (or array of valid keys). Alternatively accepts a predicate indicating which keys to pick. -
pick var book = { title: 'The Idiot', author: 'Fyodor
Dostoyevsky', year: 1869 }; _.pick(book, 'title', 'year'); _.pick(book function(val, key, obj) { return _.isNumber(val); }); -
pick var book = { title: 'The Idiot', author: 'Fyodor
Dostoyevsky', year: 1869 }; _.pick(book, 'title', 'year'); // => { title: 'The Idiot', year: 1869 } _.pick(book function(val, key, obj) { return _.isNumber(val); }); -
pick var book = { title: 'The Idiot', author: 'Fyodor
Dostoyevsky', year: 1869 }; _.pick(book, 'title', 'year'); // => { title: 'The Idiot', year: 1869 } _.pick(book function(val, key, obj) { return _.isNumber(val); }); // => { year: 1869 } -
omit Underscore.js docs: Inverse of pick(); instead of a whitelist,
it accepts a blacklist of keys to remove from object copy. -
omit var book = { title: 'The Idiot', author: 'Fyodor
Dostoyevsky', year: 1869 }; _.omit(book, 'author'); _.omit(book, function (val, key, obj) { return _.isString(val); }); -
omit var book = { title: 'The Idiot', author: 'Fyodor
Dostoyevsky', year: 1869 }; _.omit(book, 'author'); // => { title: 'The Idiot', year: 1869 } _.omit(book, function (val, key, obj) { return _.isString(val); }); -
omit var book = { title: 'The Idiot', author: 'Fyodor
Dostoyevsky', year: 1869 }; _.omit(book, 'author'); // => { title: 'The Idiot', year: 1869 } _.omit(book, function (val, key, obj) { return _.isString(val); }); // => { year: 1869 } -
defaults Underscore.js docs: Fill in undefined properties in object with
the first value present in the following list of defaults objects. -
defaults var account = { balance: 100 }; _.defaults(account, {
balance: 0, type: 'business' }); -
defaults var account = { balance: 100 }; _.defaults(account, {
balance: 0, type: 'business' }); // => { balance: 100, type: 'business' } -
property / propertyOf Underscore.js docs: property() - Returns a function
that will itself return the key property of any passed-in object. propertyOf() - Inverse of _.property. Takes an object and returns a function which will return the value of a provided property. -
property / propertyOf var book = { title: 'Ulysses' };
'Ulysses' === _.property('title')(book); _.propertyOf(book)('title'); -
property / propertyOf var book = { title: 'Ulysses' };
'Ulysses' === _.property('title')(book); // => true _.propertyOf(book)('title'); -
property / propertyOf var book = { title: 'Ulysses' };
'Ulysses' === _.property('title')(book); // => true _.propertyOf(book)('title'); // => 'Ulysses' -
matcher Underscore.js docs: Returns a predicate function that will tell
you if a passed in object contains all of the key/value properties present in attrs. -
matcher var seats = [ { num: 7, occupied: false
}, { num: 8, occupied: true }, { num: 9, occupied: false } ]; var avail = _.matcher({ occupied: false }); _.filter(seats, avail); -
matcher var seats = [ { num: 7, occupied: false
}, { num: 8, occupied: true }, { num: 9, occupied: false } ]; var avail = _.matcher({ occupied: false }); _.filter(seats, avail); // => [ { num: 7, ... }, { num: 9, ... } ] -
is* functions isArguments isEqual isNumber isArray isFinite isObject isBoolean isFunction
isRegExp isDate isMatch isString isElement isNaN isUndefined isEmpty isNull Underscore.js provides a number of handy matchers for more complex comparisons. -
tap Underscore.js docs: Invokes interceptor with the object, and then
returns object. 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 _.chain([ -2, -1, 0, 1, 2 ]) .filter(function (n)
{ return n > 0; }) .tap(alert) .map(function (n) { return n * 10; }) .value(); -
tap _.chain([ -2, -1, 0, 1, 2 ]) .filter(function (n)
{ return n > 0; }) .tap(alert) .map(function (n) { return n * 10; }) .value(); // => [ 1, 2 ] (alerted) -
tap _.chain([ -2, -1, 0, 1, 2 ]) .filter(function (n)
{ return n > 0; }) .tap(alert) .map(function (n) { return n * 10; }) .value(); // => [ 1, 2 ] (alerted) // => [ 10, 20 ] -
Function helpers – identity Underscore.js docs: Returns it's first argument.
In math: f(x) = x var obj = { name: 'Foo' }; obj === _.identity(obj); -
Function helpers – identity Underscore.js docs: Returns it's first argument.
In math: f(x) = x var obj = { name: 'Foo' }; obj === _.identity(obj); // => true -
Function helpers – constant Underscore.js docs: Function generator, new function
always returns the first argument of the generator invocation. var obj = { name: 'Foo' }; obj === _.constant(obj)(); -
Function helpers – constant Underscore.js docs: Function generator, new function
always returns the first argument of the generator invocation. var obj = { name: 'Foo' }; obj === _.constant(obj)(); // => true -
Function helpers – noop Underscore.js docs: Returns undefined irrespective of
the arguments passed to it. Useful as the default for optional callback arguments. obj.initialize = _.noop; -
Function helpers – times Underscore.js docs: Invokes iteratee exactly n
times, each time passing call index as a first argument. Returns an array of results of each invocation. _.times(3, function (n) { console.log((99 - n) + ' bottles of beer on the wall'); }); -
Math, time & ID helpers – random Underscore.js docs: Returns
a random integer between min and max, inclusive. Passing only one argument defaults to random(0, n). _.random(0, 100); // => 42 -
Math, time & ID helpers – now Underscore.js docs: Returns
UTC timestamp in milliseconds, using the fastest available method. _.now(); // => 139206679535 -
Math, time & ID helpers – uniqueId Underscore.js docs: Returns
a globally-unique id, with optional prefix appended to it. _.uniqueId('contact_'); // => 'contact_104' -
result Underscore.js docs: If the value of the named property
is a function then invoke it with the object as context; otherwise, return it. If a default value is provided and the property doesn't exist or is undefined then the default will be returned. If defaultValue is a function its result will be returned. -
result var obj = { name: 'Foo', date: function ()
{ return new Date(); } }; _.result(obj, 'name'); _.result(obj, 'date'); _.result(obj, 'bogus', 'bar'); -
result var obj = { name: 'Foo', date: function ()
{ return new Date(); } }; _.result(obj, 'name'); // => "Foo" _.result(obj, 'date'); _.result(obj, 'bogus', 'bar'); -
result var obj = { name: 'Foo', date: function ()
{ return new Date(); } }; _.result(obj, 'name'); // => "Foo" _.result(obj, 'date'); // => Tue Jun 30... _.result(obj, 'bogus', 'bar'); -
result var obj = { name: 'Foo', date: function ()
{ return new Date(); } }; _.result(obj, 'name'); // => "Foo" _.result(obj, 'date'); // => Tue Jun 30... _.result(obj, 'bogus', 'bar'); // => "bar" -
escape / unescape Underscore.js docs: escape(string) - Escapes a string
for insertion into HTML, replacing &, <, >, ", `, and ' characters. unescape(string) – The opposite of escape, replaces &, <, >, ", ` and ' with their unescaped counterparts. -
escape / unescape _.escape('Tom & Jerry'); // => "Tom &
Jerry" _.unescape('Tom & Jerry'); -
escape / unescape _.escape('Tom & Jerry'); // => "Tom &
Jerry" _.unescape('Tom & Jerry'); // => "Tom & Jerry" -
template Underscore.js docs: Compiles JS templates into functions that can
be evaluated for rendering. Useful for rendering complicated bits of HTML from JSON data sources. Template functions can interpolate values, using <%= … %>, and execute arbitrary JS code, with <% … %>. If you wish to interpolate a value, and have it be HTML-escaped, use <%- … %>. -
template var tpl = _.template("Hello <%= name %>!"); tpl({ name:
'World' }); var tpl = _.template("<b><%- val %></b>"); template({ val: '<script>' }); -
template var tpl = _.template("Hello <%= name %>!"); tpl({ name:
'World' }); // => "Hello World!" var tpl = _.template("<b><%- val %></b>"); template({ val: '<script>' }); -
template var tpl = _.template("Hello <%= name %>!"); tpl({ name:
'World' }); // => "Hello World!" var tpl = _.template("<b><%- val %></b>"); template({ val: '<script>' }); // => "<b><script></b>" -
mixin Underscore.js docs: Allows you to extend Underscore with your
own utility functions. Pass a hash of {name: function} definitions to have your functions added to the Underscore object, as well as the OOP wrapper. -
mixin _.mixin({ second: function(array) { return array[1]; } }); _([
"foo", "bar", "baz" ]).second(); -
mixin _.mixin({ second: function(array) { return array[1]; } }); _([
"foo", "bar", "baz" ]).second(); // => "bar" -
Chaining Underscore.js docs: chain(obj) - Returns a wrapped object. Calling
methods (like map, filter, find, etc.) on this object will continue to return wrapped objects until value() is called. -
Chaining var priorities = [ { name: 'high', val: 5
}, { name: 'medium', val: 3 }, { name: 'low', val: 1 } ]; _.chain(priorities) .sortBy('val') .map(function (p) { return p.name; }) .last() .value(); -
Chaining var priorities = [ { name: 'high', val: 5
}, { name: 'medium', val: 3 }, { name: 'low', val: 1 } ]; _.chain(priorities) .sortBy('val') .map(function (p) { return p.name; }) .last() .value(); // => 'high'