All notes
Lodash

Intro

Lodash makes JavaScript easier by taking the hassle out of working with arrays, numbers, objects, strings, etc.

lodash.com.

Import



// Load the full build.
var _ = require('lodash');

// Load method categories.
var array = require('lodash/array');
var object = require('lodash/fp/object');
 
// Cherry-pick methods for smaller browserify/rollup/webpack bundles.
var at = require('lodash/at');
var curryN = require('lodash/fp/curryN');

Lang



_.isUndefined(void 0);
// => true
_.isUndefined(null);
// => false

Array



////// Split into chunks.
_.chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
_.chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]

////// Remove all nil's.
_.compact([0, 1, false, 2, '', 3]);
// => [1, 2, 3]

////// Concat.
_.concat([1], 2, [3], [[4]]);
// => [1, 2, 3, [4]]

////// difference
_.difference([2, 1], [2, 3]);
// => [1]
_.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
// => [1.2]
// The `_.property` iteratee shorthand.
_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
// => [{ 'x': 2 }]

////// drop
_.drop([1, 2, 3]);
// => [2, 3]
_.drop([1, 2, 3], 2);
// => [3]
_.drop([1, 2, 3], 5);
// => []
_.drop([1, 2, 3], 0);
// => [1, 2, 3]
_.dropRight([1, 2, 3]);
// => [1, 2]

////// fill
_.fill(Array(3), 2);
// => [2, 2, 2]
_.fill([4, 6, 8, 10], '*', 1, 3);
// => [4, '*', '*', 10]

Collection

orderBy, sortBy



//---------- orderBy

// Like _.sortBy except that it allows specifying the sort orders of the iteratees to sort by.
// By default, in ascending order.

var users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 34 },
  { 'user': 'fred',   'age': 40 },
  { 'user': 'barney', 'age': 36 }
];

// Sort by `user` in ascending order and by `age` in descending order.
_.orderBy(users, ['user', 'age'], ['asc', 'desc']);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]

//---------- sortBy

// sortBy performs a stable sort.
// Only sort in ascending order.

var users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 40 },
  { 'user': 'barney', 'age': 34 }
];

_.sortBy(users, [function(o) { return o.user; }]);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]

_.sortBy(users, ['user', 'age']);
// => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]

Function

once

Creates a function that is restricted to invoking func once. Repeat calls to the function return the value of the first invocation.

wrap



var p = _.wrap(_.escape, function(func, text) {
  return '<p>' + func(text) + '</p>';
});
 
p('fred, barney, & pebbles');
// => '<p>fred, barney, &amp; pebbles</p>'

Object

mapValues



var users = {
  'fred':    { 'user': 'fred',    'age': 40 },
  'pebbles': { 'user': 'pebbles', 'age': 1 }
};

_.mapValues(users, function(o) { return o.age; });
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)

// The `_.property` iteratee shorthand.
_.mapValues(users, 'age');
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)

pick, pickBy, omitBy



var object = { 'a': 1, 'b': '2', 'c': 3 };
 
_.pick(object, ['a', 'c']);
// => { 'a': 1, 'c': 3 }

_.pickBy(object, _.isNumber);
// => { 'a': 1, 'c': 3 }

_.omit(object, ['a', 'c']);
// => { 'b': '2' }

_.omitBy(object, _.isNumber);
// => { 'b': '2' }

values, valuesIn



function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

_.values(new Foo);
// => [1, 2] (iteration order is not guaranteed)
_.valuesIn(new Foo);
// => [1, 2, 3] (iteration order is not guaranteed)

_.values('hi');
// => ['h', 'i']

Event Functions

bind

Important: use native bind instead! See below.



function greet(greeting, punctuation) {
  return greeting + ' ' + this.user + punctuation;
}
 
var object = { 'user': 'fred' };
 
var bound = _.bind(greet, object, 'hi');
bound('!');
// => 'hi fred!'
 
// Bound with placeholders.
var bound = _.bind(greet, object, _, '!');
bound('hi');
// => 'hi fred!'

Use native bind instead!

github.com: appium issues.



_.bind(function(foo) {
  // my awesome function
}, this);

//----- Instead, we prefer native bind:

function(foo) {
  // my awesome function
}.bind(this);

debounce, throttle, requestAnimationFrame

A very good article by a FE expert: css-tricks.com.

debounce: Grouping a sudden burst of events (like keystrokes) into a single one.

throttle: Guaranteeing a constant flow of executions every X milliseconds. Like checking every 200ms your scroll position to trigger a CSS animation.

requestAnimationFrame: a throttle alternative. When your function recalculates and renders elements on screen and you want to guarantee smooth changes or animations. Note: no IE9 support.

To trigger the function execution immediately, so it behaves exactly as the original non-debounced handler, use "{leading:true, trailing:false}". By default, only the trailing edge is enabled.



// WRONG
$(window).on('scroll', function() {
  _.debounce(doSomething, 300);
});

// RIGHT
$(window).on('scroll', _.debounce(doSomething, 200));