Skip to content

JasonPollman/ProtoLib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ProtoLib


The namespace friendly prototype library.

There's nothing wrong with modifying built-in prototypes, as long as you do it right.


Some of the magic from Javascript comes from the ability to modify built-in types—but it's also taboo.
It can lead to dangerous library collisions.

That's where ProtoLib comes to the rescue. It's is a fast, Node.js and browser friendly JavaScript library that "tucks" utility methods inside a single, customizable property added to Object.prototype.

Static utility methods are cumbersome and don't lend themselves to easy reading. Basically, I grew tired of using static libraries and re-writing utility methods over various projects... enter ProtoLib.

Currently tested and working in Node.js, Chrome, Firefox, Safari, IE 10 & 11.

Features


  • Over 100 library methods
    • See the list below...
    • Methods are attached to Object.prototype, which means terse, readable code.
    • Iterating functions like each, every, and any work on objects, arrays, strings, numbers, and functions.
  • Collision Free
    • You define the property attached to Object.prototype.
    • The default is _ (underscore), but this can be set to any string.
    • No ES6 for browser compatibility.
  • Extensible
    • ProtoLib allows you to extend the library for any prototype.
    • Extend both custom objects and primitives.
  • Switch the library on and off, on the fly

Contents


  1. Install
  2. Getting Started
  3. Available Methods
  4. Extending ProtoLib
  5. Advanced

Install


$ npm install proto-lib --save

Getting Started


Node.js

// Require the protolib library.
var ProtoLib = require('proto-lib');

// Get a new instance, specifying the accessor property (i.e. "handle").
// This will default to '_' if unspecified.
var lib = ProtoLib.get('_');

// That's it!
// All objects now have access to the defined library methods from the '_' property.
var str = 'hello world!';

str._.titleCase() // -> 'Hello World!'
str._.ucFirst()   // -> 'Hello world!'
str._.reverse()   // -> '!dlrow olleh'

// Chaning with ProtoLib:
str._.titleCase()._.reverse()) // ->'!dlroW olleH'

Oh Noes! I'm using a library that uses '_', what can I do?

var ProtoLib = require('proto-lib');

// Just get a new ProtoLib instance with a different handle.
var lib = ProtoLib.get('lib'),
    obj = { foo: 'hello', bar: 'world' };

obj.lib.invert()        // -> { hello: 'foo', world: 'bar' }
   .lib.histogram()     // -> { 'foo': 1, 'bar': 1 }
   .lib.size()          // -> 2

Any handle attached to Object.prototype by ProtoLib is both configurable and writable.

Do not use new with ProtoLib

Use ProtoLib's static function: ProtoLib.get.
It should be used to prevent the instantiation new ProtoLib instances across files. By using ProtoLib.get you can retrieve the same instance of the library across namespaces.

// Bad, don't do it.
var lib = new ProtoLib('_');

// Correct way to instantiate ProtoLib...
var lib = ProtoLib.get('_');

// You can create multiple instances using get...
// Not sure why you'd want to, however.
var lib  = ProtoLib.get('a');
var lib2 = ProtoLib.get('b');

Example: Cross-file use:
foo.js

var ProtoLib = require('proto-lib'),
    lib      = ProtoLib.get('_');

// Library now available to objects...
'string'._.reverse();

bar.js

// If called after foo.js, bar.js will still have the library methods attached.
// This still works...
'string'._.reverse();

// However, just to be safe you should include the library at the top of each file.
// If you don't need a reference to the class itself, just call:
require('proto-lib').get('_');

Browser Use

Use /dist/protolib.min.js... /index.js is for Node.js only.

my-html-file.hmtl

<script type="text/javascript" src="path/to/protolib.min.js"></script>
<script type="text/javascript" src="my-script.js"></script>

my-script.js

var lib = window.ProtoLib.get('_');
var arr = [1, 2, 3, 4];

arr._.rotate('left', 2)                 // -> [3, 4, 1, 2]
arr._.intersect([1, 5, 6], [9, 3, 4])   // -> [3, 4, 1]
arr._.without(4, 1)                     // -> [3]

// Chaining some methods together:
arr = [1, 2, 'hello', 'world', { foo: 'bar' }];

arr._.only('string')                   // -> ['hello', 'world']
   ._.each(function (val, key) {       // -> ['dlrow', 'olleh']
        this[key] = val._.reverse();
   });

Available Methods

Note: npm truncates this file... view the full read me on GitHub


Methods available to all Objects (objects, arrays, strings, functions, etc.).

Name Description
any Loops through each item in an object until a non-undefined value is returned
clone Clones an object using JSON.stringify and JSON.parse
copy Creates a shallow copy of an object
each Loops through each item in an object, with an optional start and end range
every Loops through each item in an object until false is returned
findChildAtPath Walks an object's children and returns the child specified by a string path
first Gets the first n items of an object
getCallback Gets the callback (last) value from a set, or returns an empty function
getNumeric Gets an object's numeric equivalent (or NaN)
histogram Computes an object's histogram of values
implements Determines if an object has the given property, and that property is a method
implementsOwn Determines if an object has the given property, and that property is a method which belongs to the object
invert Inverts an object's keys and values, or computes the mathematical inverse of a number
isArguments Determines if the given objects are all Arguments objects
isArray Determines if the given objects are all arrays
isBoolean Determines if the given objects are all booleans
isEmpty Determines if the given objects are all empty (not null, not undefined, and not an empty string)
isFunction Determines if the given objects are all functions
isNumeric Determines if the given objects are all numeric (can be parsed as a number)
isNull Determines if the given objects are all null
isPureObject Determines if the given objects are all objects (and not arrays)
isString Determines if the given objects are all strings
isUndefined Determines if the given objects are all undefined
keyOfMax Returns the key of the highest value in an object
keyOfMin Returns the key of the highest value in an object
keys Gets an object's key set
last Gets the last n items of an object
max Finds the maximum value in an object
min Finds the minimum value in an object
occurrencesOf Counts an object's occurrences of the provided arguments
random Gets a random item from the object
size Gets the size ("length") of an object
toArray Converts an object to an array
toNumber Gets an object's numeric equivalent (or NaN)
toInt Gets an object's integer equivalent (or NaN)
only Filters an object by the given types
uniqueId Gets a unique id for non-literal types
where Filters an object using a predicate function
whereKeys Filters an object by its keys using a predicate function

Methods available to all String objects.

Name Description
addSlashes Creates an eval-safe string, by escaping /['"\t\n\f\r\u0000]/
camelize Converts a string to camel case
decamelize Converts a camel cased string to sentance form
ellipses Truncates a string, adding ellipses if the string is longer than length
htmlDecode Unescapes HTML special characters
htmlEncode Escapes HTML special characters
lcFirst Lowercases the first character of a string
ltrim Left trims whitespace from a string
newlineToBreak Replaces newlines with br tags
pad Pads (or truncates) a string to length
randomString Generate a random string with the given length
regexpSafe Returns a regular expression safe string
repeat Repeats a string n times
reverse Reverses a string
rtrim Right trims whitespace from a string
splice Splices a string like Array.splice
shuffle Shuffles a string
tabsToSpan Converts tab characters to a "tab" span
titleCase Converts a string to title case
toJSValue Converts 'true', 'false', 'null', and 'undefined' to it's JS equivalent and parses numeric values as a number
ucFirst Uppercases the first character of a string
withoutTrailingSlash Removes trailing slashes from a string
withTrailingSlash Adds a trailing slash to a string

Methods available to all Array objects and their inheritors.

Name Description
ascending Sorts an array in ascending order
descending Sorts an array in descending order
difference Computes the set difference of the given arrays
intersect Computes the set intersection of the given arrays
makeUnique Removes duplicates from the array (modifies the array)
unique Returns a new array with duplicates removed
rotate Rotates an array's contents left or right
rotateLeft Rotates an array's contents left
rotateRight Rotates an array's contents right
shuffle Shuffles the contents of an array
union Computes the unique union of the given arrays
without Returns a new array with all occurrences of the arguments omitted

Methods available to all Function objects and their inheritors.

Name Description
inherits Inherit the prototype methods from one constructor into another

Methods available to all Number objects and their inheritors.

Name Description
choose Computes n choose k
clockTime Returns a string in the HH:MM:SS:MSEC format
daysAgo Gets a date that occurs n days ago
daysFrom Gets a date that occurs n days from the given date
daysFromNow Gets a date that occurs n days from the current date
factorial Returns the factorial of a number
formatMoney Returns a money formatted string
hoursAgo Gets a date that occurs n hours ago
hoursFrom Gets a date that occurs n hours from the given date
hoursFromNow Gets a date that occurs n hours from the current time
isInt True if all arguments are integers, false otherwise
minutesAgo Gets a date that occurs n minutes ago
minutesFrom Gets a date that occurs n minutes from the given date
minutesFromNow Gets a date that occurs n minutes from the current time
monthsAgo Gets a date that occurs n months ago
monthsFrom Gets a date that occurs n months from the given date
monthsFromNow Gets a date that occurs n months from the current date
pad Pads a number with leading (or trailing) zeros
randomNumberInRange Get a random number in the range [min, max] (inclusive)
randomIntInRange Get a random integer in the range [min, max] (inclusive)
secondsAgo Gets a date that occurs n seconds ago
secondsFrom Gets a date that occurs n seconds from the given date
secondsFromNow Gets a date that occurs n seconds from the current time
to Returns a random integer (if passed an int), or float (if passed a float) in the given range
withPlaceholders Adds commas to a number
yearsAgo Gets a date that occurs n years ago
yearsFrom Gets a date that occurs n years from the given date
yearsFromNow Gets a date that occurs n years from the current date
yyyymmdd Returns a number in the YYYY-MM-DD format

Methods available to all Date objects and their inheritors.

Name Description
advanceDays Advances the date n days
advanceMonths Advances the date n months
advanceYears Advances the date n years
clockTime Returns a string in the HH:MM:SS:MSEC format
yyyymmdd Returns a number in the YYYY-MM-DD format

The examples below assume you have set 'lib' to a new instance of ProtoLib and that you're using the default handler ('_'), that is...

var ProtoLib = require('proto-lib'),
    lib = ProtoLib.get('_');

// Or in the browser...
var lib = window.ProtoLib.get('_');

Objects

histogram

Returns an object containing a frequencies of values.
For objects (arrays and pure objects), it will count the frequency of values. For strings, it will count character frequencies. Numbers and functions will be converted using toString.

Context Signature
instance histogram() → {Object}
static histogram({...*} items) → {Object}
[1, 2, 3, 4, 1, 1, 1, 5, 5]._.histogram()
// Returns { 1: 4, 2: 1, 3: 1, 4: 1, 5: 2 }

'racecar'._.histogram()
// Returns { r: 2, a: 2, c: 2, e: 1 }

'AAAAaaaa'._.histogram()
// Returns { A: 4, a: 4 }

(1234).histogram()
// Returns { 1: 1, 2: 1, 3: 1, 4: 1 }

(-1234).histogram()
// Returns { '-': 1, 1: 1, 2: 1, 3: 1, 4: 1 }

{ foo: 'bar', hello: 'world', number: 5, five: 5 }._.histogram()
// Returns { bar: 1, world: 1, 5: 2 }

/* Static Use */

lib.object.histogram([1, 2, 3], 'a string', function () {});
// Returns { 1: 1, 2: 1, 3: 1, a: 1, ' ': 1, s: 1, t: 1, r: 1, i: 1, n: 1, g: 1, 'function': 1 }

lib.object.histogram([1, 2, 3, [3, 4, 5], ['a', 'b', 'c']]);
// Returns { 1: 1, 2: 1, 3: 1, array: 2 }

copy

Returns a shallow copy of an object.
For non-objects, the provided value is simply returned. For objects, a shallow copy is made.

Context Signature
instance copy() → {*}
static copy({*} item) → {*}
[1, 2, 3, 'a', 'b', 'c']._.copy();
// Returns a copy of the above array.

{ foo: 'bar' }._.copy();
// Returns a copy of the above object.

'hello world'._.copy();
// Returns 'hello world'

/* Static Use */
lib.object.copy(something);

occurrencesOf

Counts the number of occurrences of what.

Context Signature
instance occurrencesOf({*} what) → {Number}
static occurrencesOf({*} item, {*} what) → {Number}
[1, 1, 1, 1, 3]._.occurrencesOf(1);
// Returns 4

[1, 1, 1, 1, 3]._.occurrencesOf('1');
// Returns 0

{ foo: 'bar', hello: 'world' }._.occurrencesOf('bar');
// Returns 1

'racecar'._.occurrencesOf('r');
// Returns 2

'the rain falls mainly in the plain in spain'._.occurrencesOf('ain');
// Returns 4


/* Static Use */
lib.object.occurrencesOf(haystack, needle);

keys

Returns the object's key set.
Note: For numbers and functions, this will always return an empty array.

Context Signature
instance keys() → {Array}
static keys({*} item) → {Array}
[1, 1, 1, 1, 3]._.keys();
// Returns ['0', '1', '2', '3', '4']

{ foo: 'bar', baz: 'biz' }._.keys();
// Returns ['foo', 'bar']

'a string'._.keys();
// Returns ['0', '1', '2', '3', '4', '5', '6', '7']

(1234)._.keys();
// Returns []

(function () {})._.keys();
// Returns []

/* Static Use */
lib.object.keys(item);

size

Returns the "size" of an object (length).
For strings, it will return the string's length, for numbers: the number of digits, for objects: Object.keys(...).length, for arrays: Array.length, and for functions: 1.

Context Signature
instance size() → {Number}
static size({*} item) → {Number}
[1, 1, 1, 1, 3]._.size();
// Returns 5

{ foo: 'bar', baz: 'biz' }._.size();
// Returns 2

'a string'._.size();
// Returns 8

(1234)._.size();
// Returns 4

(-1234)._.size();
// Returns 5

(function () {})._.size();
// Returns 1

/* Static Use */
lib.object.size(item);

isNumeric

Determines if the object "is numeric".
Returns true if the object can be parsed as a number and is finite, false otherwise.
If used in the static context, it will return true if and only if all arguments are numeric.

Context Signature
instance isNumeric() → {Boolean}
static isNumeric({...*} items) → {Boolean}
[]._.isNumeric();               // false
{}._.isNumeric();               // false

'string'._.isNumeric();         // false
'1234'._.isNumeric();           // true
'-1234'._.isNumeric();          // true
'1e7'._.isNumeric();            // true
'0xFF'._.isNumeric();           // true

(1234)._.isNumeric();           // true
(-1234)._.isNumeric();          // true
(1e7)._.isNumeric();            // true
(0x64)._.isNumeric();           // true

(function () {})._.isNumeric(); // false

/* Static Use */
lib.object.isNumeric(a, b, c...);

getNumeric

Get's an object's number equivalent.
Returns the number represented by the given value, or NaN.
If used in the static context, it will return an array with the results for each argument if more than one argument is supplied.

Context Signature
instance getNumeric() → {Number|NaN}
static getNumeric({...*} objs) → {Number|NaN}
[]._.getNumeric();               // NaN
{}._.getNumeric();               // NaN

'string'._.getNumeric();         // NaN
'1234'._.getNumeric();           // 1234
'-1234'._.getNumeric();          // -1234
'-1234.56'._.getNumeric();       // -1234.56
'1e7'._.getNumeric();            // 10000000
'0xFF'._.getNumeric();           // 255

(1234)._.getNumeric();           // 1234
(1234.56)._.getNumeric();        // 1234.56
(-1234)._.getNumeric();          // -1234
(1e7)._.getNumeric();            // 10000000
(0x64)._.getNumeric();           // 100

(function () {})._.isNumeric();  // NaN

/* Static Use */
lib.object.getNumeric('1', '0xFF', 'hello world', 7); // Returns [1, 255, NaN, 7]
lib.object.getNumeric('90'); // Returns 90

isEmpty

Determines if the given objects are "empty".
That is, if obj !== null && obj !== undefined && obj !== ''. So zero (0) isn't empty.
For collections, it will assert that the object has a length of more than zero.

If used in the static context, it will return true if and only if all arguments are empty.

Context Signature
instance isEmpty() → {Boolean}
static isEmpty({...*} objs) → {Boolean}
[]._.isEmpty()                // true
{}._.isEmpty()                // true
[1]._.isEmpty()               // false
{ foo: 1, bar: 2}._.isEmpty() // false
(0)._.isEmpty()               // false
''._.isEmpty()                // true
'hello world'._.isEmpty()     // false
function () {}._.isEmpty()    // false

/* Static Use */
lib.object.isEmpty(0, '', 1, []);    // false
lib.object.isEmpty([], {}, []);      // true
lib.object.isEmpty(null, undefined); // true

isArray

Determines if the given objects are all arrays.
If used in the static context, it will return true if and only if all arguments are arrays.

Context Signature
instance isArray() → {Boolean}
static isArray({...*} objs) → {Boolean}
[]._.isArray()                // true
{}._.isArray()                // false
[1]._.isArray()               // true
{ foo: 1, bar: 2}._.isArray() // false
'hello world'._.isArray()     // false
function () {}._.isArray()    // false

/* Static Use */
lib.object.isArray(0, [], [1, 2, 3]);               // false
lib.object.isArray([], [1, 2, 3], ['a', 'b', 'c']); // true
lib.object.isArray(null, []);                       // false

isPureObject

Determines if the given objects are all objects, but not arrays.
If used in the static context, it will return true if and only if all arguments are "pure objects".

Context Signature
instance isPureObject() → {Boolean}
static isPureObject({...*} objs) → {Boolean}
[]._.isPureObject()                // false
{}._.isPureObject()                // true
[1]._.isPureObject()               // false
{ foo: 1, bar: 2}._.isPureObject() // true
'hello world'._.isPureObject()     // false
function () {}._.isPureObject()    // false

/* Static Use */
lib.object.isPureObject({}, {}, {}); // true
lib.object.isPureObject([], {});     // false
lib.object.isPureObject(null, {});   // false

isString

Determines if the given objects are all strings.
If used in the static context, it will return true if and only if all arguments are strings.

Context Signature
instance isString() → {Boolean}
static isString({...*} objs) → {Boolean}

isBoolean

Determines if the given objects are all booleans. If used in the static context, it will return true if and only if all arguments are booleans.

Context Signature
instance isBoolean() → {Boolean}
static isBoolean({...*} objs) → {Boolean}

isFunction

Determines if the given objects are all functions.
If used in the static context, it will return true if and only if all arguments are functions.

Context Signature
instance isFunction() → {Boolean}
static isFunction({...*} objs) → {Boolean}

isNull

Determines if the given objects are all null.
If used in the static context, it will return true if and only if all arguments are null.

Context Signature
instance isNull() → {Boolean}
static isNull({...*} objs) → {Boolean}

isUndefined

Determines if the given objects are all undefined.
If used in the static context, it will return true if and only if all arguments are undefined.

Context Signature
instance isUndefined() → {Boolean}
static isUndefined({...*} objs) → {Boolean}

isArguments

Determines if the given objects are all arguments objects.
If used in the static context, it will return true if and only if all arguments are Arguments instances.

Context Signature
instance isArguments() → {Boolean}
static isArguments({...*} objs) → {Boolean}
[]._.isArguments()                // false
{}._.isArguments()                // false
[1]._.isArguments()               // false
{ foo: 1, bar: 2}._.isArguments() // false
'hello world'._.isArguments()     // false
function () {}._.isArguments()    // false

(function () {
    arguments._.isArguments()     // true
}());

/* Static Use */

(function () {
    lib.object.isArguments(arguments); // true
}());

lib.object.isArguments([]);            // false

toNumber

Alias for getNumeric

toInt

Get's the object's integer equivalent.
Returns the integer value represented by the given value(s), or NaN. If used in the static context, it will return an array with the results for each argument if more than one argument is supplied.

Context Signature
instance toInt()
static toInt({...*} objs)
[]._.toInt();               // NaN
{}._.toInt();               // NaN

'string'._.toInt();         // NaN
'1234.12'._.toInt();        // 1234
'-1234.000112'._.toInt();   // -1234
'1e7'._.toInt();            // 10000000
'0xFF'._.toInt();           // 255

(1234.789)._.toInt();       // 1234
(-1234.00012)._.toInt();    // -1234
(1e7)._.toInt();            // 10000000
(0x64)._.toInt();           // 100

(function () {})._.toInt();  // NaN

/* Static Use */
lib.object.toInt('1', '0xFF', 'hello world', 7); // Returns [1, 255, NaN, 7]

random

Returns a random item from an array or object, a random digit from a number, or a random character from a string.
Functions are cast to strings with Function.toString

Context Signature
instance random() → {*}
static random({*} obj) → {*}
[1, 2, 3, 4].random()._.random();         // Could be any of: 1, 2, 3, or 4
{ foo: 'a', bar: 'b', baz: 0 }._.random() // Could be any of: 'a', 'b', 0,
'string'._.random()                       // Could be any of: 's', 't', 'r', 'i', 'n', 'g'

/* Static Use */
lib.object.random([[1, 2, 3], ['a', 'b', 'c'], 9]);
// Returns either one of the arrays or 9

each

Invokes the provided callback for "each" item in the collection.
For each item in the collection, a callback (onIteration) is invoked with the following arguments: this refers to the object being iterated over within the body of onIteration.

Functions and Numbers are cast to strings with Function/Number.toString.

Context Signature
instance each({Number=} [startRange=0], {Number=} [endRange=obj.length - 1], {Function} onInteration) → {*|null}
static each({*} obj, {Number=} [startRange=0], {Number=} [endRange=obj.length - 1], {Function} onInteration)) → {*|null}

Arguments passed to onInteration:

Argument Definition
{*} value The value of the current item being iterated over
{String} key The key of the current item
{Number} iteration The current iteration count.
For arrays key and iteration will be the same.
{Function} exit A function that, when called, will break the loop and return the arguments passed to it as an array (or if a single value is passed, the value itself)
{*} parent The object being iterated over.
Typically, this and parent will be equal, however the parent argument exists in the event that onIteration has been bound. If using an arrow function this will be lexically block scoped, so parent should be used instead.

Note: All ranges are inclusive. If startRange is greater than endRange it will perform a decrementing loop.

var total = 0, keyTotal = 0;
[1, 2, 3, 4, 5]._.each((val, key) => {
    total    += val;
    keyTotal += key.toString();
});
// total    = 15
// keyTotal = '01234'

{ hello: 1, world: 'foo', array: [1, 2, 3] }._.each((val, key, i, exit) => {
    console.log(val + ',' + key + ',' + i);
});
// Logged on 0th iteration: 1, 'hello', 0
// Logged on 1st iteration: 'foo', 'world', 1
// Logged on 2nd iteration: 1,2,3, 'array', 2

var truncated = '';
var result = 'hello world!'._.each((val, key, i, exit) => {
    if(val === ' ') return exit(val);
    truncated += val;
});
// truncated = 'hello'
// result    = ' '

/* Using Ranges */
/* All ranges are inclusive */

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr._.each(0, 3, function (val, key, i, exit) {
    this[key] *= 7;
});
// arr = [7, 14, 21, 28, 5, 6, 7, 8, 9, 10]

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr._.each(4, 3, function (val, key, i, exit, parent) {
    parent[key] *= 7;
});
// arr = [1, 2, 3, 28, 35, 6, 7, 8, 9, 10]

// If rangeA > rangeB, a decrementing loop will be performed!
arr = ['d', 'l', 'r', 'o', 'w', ' ', 'o', 'l', 'l', 'e', 'h'],
str = '';
arr._.each(10000, 0, function (val, key, i, exit) {
    str += val;
});
// str = 'hello world'

/* Static Use */
var myArray = ['a', 'b', 'c'],
    onInteration = () => { /* Do something... */ }

lib.object.each(myArray, 0, 1 onInteration);
// Iterates through 'a' and 'b', but not 'c'.

every

Invokes the provided callback for "every" item in the collection.
Loops through each item in the object and calls onIteration. If false is returned, the loop will break and return false, otherwise it will return true. This is similar to Array.every except that it works for all objects, and will break only on false and not a falsy return (null, undefined, 0, etc.). this refers to the object being iterated over within the body of onIteration.

Functions and Numbers are cast to strings with Function/Number.toString.

Context Signature
instance every({Function} onInteration) → {Boolean}
static every({*} obj, {Function} onInteration)) → {Boolean}

Arguments passed to onInteration:

Argument Definition
{*} value The value of the current item being iterated over
{String} key The key of the current item
{Number} iteration The current iteration count.
For arrays key and iteration will be the same.
{*} parent The object being iterated over.
Typically, this and parent will be equal, however the parent argument exists in the event that onIteration has been bound. If using an arrow function this will be lexically block scoped, so parent should be used instead.
var obj = { a: 1, b: 2, c: 3 },
    keys = [],
    vals = [];

obj._.every((val, key) => {
    vals.push(val);
    keys.push(key);
});
// vals = [1, 2, 3], keys = ['a', 'b', 'c']

var didLoopThroughAllItems = obj._.every(val => {
    if(val === 3) return false;
});
// didLoopThroughAllItems = false

didLoopThroughAllItems = obj._.every(val => {
    if(val === 999) return false;
});
// didLoopThroughAllItems = true

/* Static Use */
var myArray = ['a', 'b', 'c'],
    onInteration = () => { /* Do something... */ }

lib.object.every(myArray, onInteration);

any

Invokes the provided callback for every item in the collection and breaks when any value (other than undefined) is returned.
Loops through each item in the object and calls onIteration. If a "non-undefined" value is returned, the loop will break and return that value.

Functions and Numbers are cast to strings with Function/Number.toString.

Context Signature
instance any({Function} onInteration) → {*|undefined}
static any({*} obj, {Function} onInteration)) → {*|undefined}

Arguments passed to onInteration:

Argument Definition
{*} value The value of the current item being iterated over
{String} key The key of the current item
{Number} iteration The current iteration count.
For arrays key and iteration will be the same.
{*} parent The object being iterated over.
Typically, this and parent will be equal, however the parent argument exists in the event that onIteration has been bound. If using an arrow function this will be lexically block scoped, so parent should be used instead.
var obj = { a: 1, b: 2, c: 3 },
    keys = [],
    vals = [];

obj._.any((val, key) => {
    vals.push(val);
    keys.push(key);
});
// vals = [1, 2, 3], keys = ['a', 'b', 'c']

var result = obj._.any(val => {
    if(val === 3) return val;
});
// result = 3

result = obj._.any(val => {
    if(val === 999) return val;
});
// result = undefined

result = 'hello world'._.any(function (val, key) {
    if(key == 4) return 'got the letter o';
});
// result = 'got the letter o'

/* Static Use */
var myArray = ['a', 'b', 'c'],
    onInteration = () => { /* Do something... */ }

lib.object.any(myArray, onInteration);

toArray

Converts an object to an array.
Useful for converting arguments objects to arrays. If an array is passed, a shallow copy of the array will be returned.

Context Signature
instance toArray() → {Array<*>}
static toArray({*} obj) → {Array<*>}
var string = 'a string',
    chars  = string._.toArray(); // chars = ['a', ' ', 's', 't', 'r', 'i', 'n', 'g']

var obj = { foo: 1, bar: 2 },
    arr = obj._.toArray(); // arr = [1, 2]

(function () {
    var args = arguments._.toArray();
    // args = [1, 2, 3, 4]
}(1, 2, 3, 4));

/* Static Use */
var converted = lib.object.toArray({ a: [1, 2], b: { foo: 'bar' }});
// converted = [[1, 2], { foo: 'bar' }]

first

Returns the first n items of an object.
If n is 1, the first item will be returned. If n is more than 1, an array/object of the first n items will be returned. IF a string is passed, a single string will always be returned... in this way it works like String.slice. Strings, numbers and functions will be cast to string using toString.

Context Signature
instance first({Number=} [n=1]) → {*|Array<*>|Object<*>}
static first({*} obj, {Number=} [n=1]) → {*|Array<*>|Object<*>}
var string = 'a string',

    first = string._.first(),
    // first = 'a'
    firstFour = string._.first(4);
    // firstTwo = 'a st'

var array = [1, 2, 3, 4],

    arrayFirst = array._.first(),
    // arrayFirst = 1

    arrayFirstThree = array._.first(3);
    // arrayFirstThree = [1, 2, 3]

var object = { foo: 'bar', hello: 'world' },

    objectFirst = object._.first(),
    // objectFirst = 'bar'

    objectFirstThree = object._.first(3);
    // objectFirstThree = { foo: 'bar', hello: 'world' }

/* Static Use */
var staticFirst = lib.object.first([1, 2, 3]);
// staticFirst = 1

last

Returns the last n items of an object.
Works similar to first, except it returns the last n items, rather than the first n,

Context Signature
instance last({Number=} [n=1]) → {*|Array<*>|Object<*>}
static last({*} obj, {Number=} [n=1]) → {*|Array<*>|Object<*>}

getCallback

Always returns a callback.
If the last item in the object is a function, it will be returned, otherwise an "empty" function is returned. This is useful for ensuring that you always have a valid callback when used against an arguments object.

This method is useless against strings, numbers, and functions. It will however, return an "empty" function if called on one.

Context Signature
instance getCallback() → {Function}
static getCallback({*} obj) → {Function}
// For this example EMPTY_CALLBACK_REPLACEMENT is a "blank" function.
// EMPTY_CALLBACK_REPLACEMENT === function () {}

var cb = [1, 2, 3, 4].getCallback();         // cb === EMPTY_CALLBACK_REPLACEMENT

cb = [1, 2, 3, function someFunction () {}]; // cb === someFunction
cb = { foo: 'bar', hello: 'world' };         // cb === EMPTY_CALLBACK_REPLACEMENT
cb = { foo: 'bar', hello: () => {} };        // cb === anonymous arrow function

(function (argA, argB, argC) {
    cb = arguments.getCallback();
    // cb === argC === exampleCallbackFunction
}('argA', 'argB', function exampleCallbackFunction () {}));

(function (argA, argB, argC, argD, argE) {
    cb = arguments.getCallback();
    // cb === EMPTY_CALLBACK_REPLACEMENT
    // Since exampleCallbackFunction wasn't the *last* argument,
    // the empty function was assigned to cb.
}('argA', 'argB', function exampleCallbackFunction () {}, 'argD', 'argE'));

/* Static Use */
var staticFirst = lib.object.getCallback(someObject);

findChildAtPath

Finds the child of an object specified by the given string path.
Finds the child specified by the given string "path" and delimiter (default '.') by walking the objects keys.

Context Signature
instance findChildAtPath({String} path, {String=} [delimiter='.'], {Function=} done) → {*|null}
static findChildAtPath({*} obj, {String} path, {String=} [delimiter='.'], {Function=} done) → {*|null}
var someObject = {
    a: {
        aa: {
            aaa: 1,
            aab: 'hello'
        },
        ab: {
            aba: 2,
            abb: 'world'
        }
    },
    b: {
        ba: {
            baa: 3,
            bab: 'foo'
        },
        bb: {
            bba: 4,
            bbb: 'bar'
        }
    },
    c: [
        100,
        200,
        {
            example: 'value'
        }
    ]
}

var aa = someObject._.findChildAtPath('a.aa'),
    // Returns the object labeled by 'aa'

    aaa = someObject._.findChildAtPath('a.aa.aaa'),
    // Returns the value labeled by 'aaa' (1)

    bba = someObject._.findChildAtPath('a.bb.bba'),
    // Returns the value labeled by 'bba' (3)

    xxy = someObject._.findChildAtPath('a.bb.xxy'),
    // Returns null

    // Works on arrays too...
    c1 = someObject._.findChildAtPath('c.1'),
    // Returns 200

    c1 = someObject._.findChildAtPath('c.2.example'),
    // Returns 'value'

    d = someObject._.findChildAtPath('d'),
    // Returns null

    xxx = someObject._.findChildAtPath('');
    // Returns someObject

// If a function is passed for parameter *done*, it will be invoked
// with the item at the path, the parent of the item, and the item's key
aa = someObject._.findChildAtPath('a.aa', function (value, parent, key) {
    // this   = someObject
    // value  = { aaa: 1, aab: 'hello' }
    // parent = the object labeled by 'a' above.
    // key    = 'aa'
});

aaa = someObject._.findChildAtPath('a.aa.aaa', function (value, parent, key) {
    // this   = someObject
    // value  = 1
    // parent = the object labeled by 'a.aa' above.
    // key    = 'aaa'
});

/* Static Use */
var child = lib.object.findChildAtPath(someObject, 'somePath');

clone

Clones an object using JSON.stringify and JSON.parse.
Throws an error if the object is circular. The optional replacer argument will be passed to JSON.stringify (see MDN's JSON.stringify).

Context Signature
instance clone({Function=} replacer) → {*}
static clone({*} obj, {Function=} replacer) → {*}
var foo, bar;

foo = { a: 1, b: 2, c: 3 };
bar = foo._.clone(); // bar = { a: 1, b: 2, c: 3 }

foo = [1, 2, 3, 4, { a: 1, b: 2}];
bar = foo._.clone(); // bar = [1, 2, 3, 4, { a: 1, b: 2}]

/* Static Use */
lib.object.clone(myObject);

only

Returns a new object with only the given types.
Filters an object by the specified list of types ('string', 'number', 'object', 'array', 'function', 'object object'). Any typeof type can be used, and multiple arguments can be specified. object will return both arrays and objects, object object will return only objects, and array will filter only arrays.

Plural forms of the types can be used as well.

Context Signature
instance only({...String} types) → {*}
static only({*} obj, {...String} types) → {*}
var foo, bar;
foo = [1, 2, 3, 'a', 'b', 'c', 4, 5, 6];

bar = foo._.only('numbers');            // bar = [1, 2, 3, 4, 5, 6]
bar = foo._.only('strings');            // bar = ['a', 'b', 'c']
bar = foo._.only('numbers', 'strings'); // bar = [1, 2, 3, 'a', 'b', 'c', 4, 5, 6]

foo = {
    a: [1, 2, 3],
    b: 'a string',
    c: function () {},
    d: null,
    e: { z: 9, y: 8 }
};

bar = foo._.only('object');         // bar = { a: [1, 2, 3], d: null, e: { z: 9, y: 8 } }
bar = foo._.only('array');          // bar = { a: [1, 2, 3] }
bar = foo._.only('object object');  // bar = { d: null, e: { z: 9, y: 8 } }
bar = foo._.only('function');       // bar = { c: function () {} }

// Useless on strings, numbers, and functions...
bar = (5)._.only('string')              // bar = 5
bar = ('hello world')._.only('string')  // bar = 'hello world'
bar = (function () {})._.only('string') // bar = function () {}

/* Static Use */
lib.object.only(myObject, 'typeA', 'typeB', 'typeC'...);

where

Returns a new object, filtering by a predicate function.
Filters an object by using a predicate function. If the predicate returns true the item is included in the results. The predicate function will be invoked for each item within the object with the following signature: onItem ({*} item, {String} key).

Context Signature
instance where({Function} predicate) → {*}
static where({*} obj, {Function} predicate) → {*}
var foo, bar;
foo = [1, 2, 3, 4];

bar = foo._.where(item => item > 2); // bar = [3, 4]
bar = foo._.where(item => true);     // bar = [1, 2, 3, 4]

foo = {
    a: [1, 2, 3],
    b: 'a string',
    c: function () {},
    d: null,
    e: { z: 9, y: 8 }
};

bar = foo._.where((item, key) => key === 'a');      // bar = { a: [1, 2, 3] }
bar = foo._.where(function (item, key) {            // bar = { b: 'a string' }
    return typeof item !== 'object' && key !== 'c';
});

/* Static Use */
lib.object.where(myObject, predicateFunction);

whereKeys

Returns a new object, filtering an object's keys by a predicate function.
The same as where, except that the predicate function is invoked with the signature: onItem ({String} key, {*} item).

Context Signature
instance whereKeys({Function} predicate) → {*}
static whereKeys({*} obj, {Function} predicate) → {*}

invert

Inverts an object's keys and values.
For numbers it computes the mathematical inverse (x-1).
For strings, it reverses the string.
For functions, invert returns a new function that wraps the given function and inverts it's result.

Context Signature
instance invert() → {*}
static invert({*} obj) → {*}
(1)._.invert()     // -> 1
(0)._.invert()     // -> Infinity
(789)._.invert()   // -> ~0.00126742712

[6, 7, 8]._.invert() // -> { 6: 0, 7: 1, 8: 2 }
{ a: 'foo', b: 5 }   // -> { foo: 'a', 5: b }
'string'._.invert()  // -> 'gnirts'
true._.invert()      // -> false

// For functions, invert returns a new function that wraps the
// given function and inverts it's result.
function alwaysTrue = () {
    return true;
}

var alwaysFalse = alwaysTrue._.invert();
alwaysFalse() // -> false

// Under the hood alwaysFalse was turned into something like this...
function () {
    return alwaysTrue.apply(alwaysTrue, arguments)._.invert();
}

/* Static Use */
lib.object.invert(myObject);

max

Get's the highest value from an object.
For numbers, strings, functions, and booleans, the object is simply returned. An optional predicate function is available to determine the max for objects. The predicate is called with the current value in the collection, whatever is returned from the predicate is used in the evaluation to determine the if the value is the max.

Context Signature
instance max({Function=} predicate) → {*}
static max({*} obj, {Function=} predicate) → {*}
[1, 4, 7, 5, 99, 1, 2]._.max()          // -> 99
['a', 'e', 'i', 'q', 'b', 'z']._.max()  // -> 'z'
[1, 'a', 4, 'r', 999]._.max()           // -> 999, since 999 > 'r' char code
{ a: 43, b: 123, c: 0 }._.max()         // -> 123

// Predicate example
var data = [
    {
        name: 'foo',
        value: 1
    },
    {
        name: 'bar',
        value: 2
    },
    {
        name: 'baz',
        value: 3
    }
];

var max = data._.max(function (item) {
    return item.value;
});

// max = { name: 'baz', value: 3 }

/* Static Use */
lib.object.max(myObject);

min

Get's the lowest value from an object.
Same as max, except it returns the minimum value.

Context Signature
instance min({Function=} predicate) → {*}
static min({*} obj, {Function=} predicate) → {*}

keyOfMax

Returns the key of the highest value in an object.
For numbers, strings, functions, and booleans, the object is simply returned. An optional predicate function is available to determine the max for objects. The predicate is called with the current value in the collection, whatever is returned from the predicate is used in the evaluation to determine the if the value is the max. When a max value is found, its key is returned.

Context Signature
instance keyOfMax({Function=} predicate) → {*}
static keyOfMax({*} obj, {Function=} predicate) → {*}

keyOfMin

Same as keyOfMax, except it returns the minimum value's key.

Context Signature
instance keyOfMin({Function=} predicate) → {*}
static keyOfMin({*} obj, {Function=} predicate) → {*}

implements

Determines if an object has the given properties, and those properties are methods.

Context Signature
instance implements({String} method) → {*}
static implements({*} obj, {String} method) → {*}
var MyClass = function () {
    this.foo = function () {};
    this.bar = 5;
    this.baz = function () {};
};

var x = new MyClass();
x._.implements('foo', 'baz'); // -> true
x._.implements('bar', 'baz'); // -> false, baz is not a method

var y = {
    orange: function () {},
    apple: false
};

y._.implements('orange'); // -> true
y._.implements('apple'); // -> false, apple is not a method

/* Static Use */
lib.object.implements(myObject);

implementsOwn

Determines if an object has the given properties, and those properties are methods which belongs to the object.
Same as implements, except with added hasOwnProperty check.

Context Signature
instance implementsOwn({String} method) → {*}
static implementsOwn({*} obj, {String} method) → {*}

uniqueId

Returns a unique id for non-literals.
Returns a unique hex string for objects and functions. Throws on numbers and strings. The id is generated on a as requested basis, so the first time it's called 0x0 is returned, then 0x1, etc. etc. However, once assigned to the object, the same id will always be returned for that object.

Context Signature
instance uniqueId() → {String}
static uniqueId({*} obj) → {String}
var obj = { foo: 1, bar: 2 },
    id  = obj._.uniqueId();  // -> '0xN', where N is some base 16 number

var arr = [1, 2, 3],
    id  = arr._.uniqueId();  // -> '0xN', where N is some base 16 number

var func = function () {},
    id  = func._.uniqueId(); // -> '0xN', where N is some base 16 number

(5).uniqueId();              // Throws an Error
('a string').uniqueId();     // Throws an Error

/* Static Use */
lib.object.uniqueId(myObject);

Strings

toJSValue

Converts 'true', 'false', 'null', and 'undefined' to it's JS equivalent and parses numeric values as a number.
The string will be trimmed. If the string value is numeric, a number will be returned. If the trimmed string is non-numeric or doesn't evaluate to true, false, null, or undefined the original (untrimmed) string will be returned.

Context Signature
instance toJSValue() → {String}
static toJSValue({String} myString) → {String}
'true'._.toJSValue()        // -> returns boolean true
'false'._.toJSValue()       // -> returns boolean false

'  true  '._.toJSValue()    // -> returns boolean true
'  false  '._.toJSValue()   // -> returns boolean false

'True'._.toJSValue()        // -> returns the original string
'falsE'._.toJSValue()       // -> returns the original string

'null'._.toJSValue()        // -> returns null
'undefined'._.toJSValue()   // -> returns undefined

'5.46'._.toJSValue()        // -> returns the number 5.46

lib.string.toJSValue(myString);

camelize

Converts a string to camel case.
Replaces /[^a-z0-9$]/g with '' and makes the first letter of each word uppercase (except the first, of course).

Context Signature
instance camelize() → {String}
static camelize({String} myString) → {String}
var myString = 'hello world!';
myString._.camelize(); // -> 'helloWorld'

"we_don't_like_underscores_in_javascript"._.camelize();
// -> 'weDontLikeUnderscoresInJavascript'

decamelize

Converts a camel case string to "somewhat" sentance form.

Context Signature
instance decamelize() → {String}
static decamelize({String} myString) → {String}
var myString = 'thisIsCamelCased';
myString._.decamelize(); // -> 'this is camel cased'

'interestingBehavior'._.decamelize();
// -> 'interesting behavior'

'interestingBEHAVIOR'._.decamelize();
// -> 'interesting b e h a v i o r'

repeat

Repeats a string n times.

Context Signature
instance repeat() → {String}
static repeat({String} myString) → {String}
var myString = 'repeat me ';
myString._.repeat(3); // -> 'repeat me repeat me repeat me '

'*'._.repeat(10);     // -> '**********'
'Racecar'._.repeat(3) // -> 'RacecarRacecarRacecar'

/* Static Use */
lib.string.repeat(myString);

ltrim

Left trims whitespace from a string.
Functions just like String.trim, except only on the left side of the string.

Context Signature
instance ltrim() → {String}
static ltrim({String} myString) → {String}

rtrim

Right trims whitespace from a string.
Functions just like String.trim, except only on the right side of the string.

Context Signature
instance rtrim() → {String}
static rtrim({String} myString) → {String}

htmlEncode

Escapes HTML special characters.

Context Signature
instance htmlEncode() → {String}
static htmlEncode({String} myString) → {String}
var myString = '5 is > 7, but 7 < 9';
myString._.htmlEncode(); // -> '5 is &gt; 7, but 7 is &lt; 9'

/* Static Use */
lib.string.htmlEncode(myString);

htmlDecode

Unescapes HTML special characters.

Context Signature
instance htmlDecode() → {String}
static htmlDecode({String} myString) → {String}
var myString = '5 is &gt; 7, but 7 is &lt; 9';
myString._.htmlDecode(); // -> '5 is > 7, but 7 < 9'

/* Static Use */
lib.string.htmlDecode(myString);

addSlashes

Creates an 'eval' safe string, by adding slashes to ", ', \t, \n, \f, \r, and the NULL byte.

Context Signature
instance addSlashes() → {String}
static addSlashes({String} myString) → {String}
var myString = 'function () { return "hello world!" };';
myString._.addSlashes(); // -> 'function () { return \"hello world!\" };'

/* Static Use */
lib.string.addSlashes(myString);

ucFirst

Returns the string with the first letter capitalized.

Context Signature
instance ucFirst() → {String}
static ucFirst({String} myString) → {String}
var myString = 'hello world!';
myString._.ucFirst(); // -> 'Hello world!'

/* Static Use */
lib.string.ucFirst(myString);

lcFirst

Returns the string with the first letter lowercased.

Context Signature
instance lcFirst() → {String}
static lcFirst({String} myString) → {String}
var myString = 'Hello world!';
myString._.lcFirst(); // -> 'hello world!'

/* Static Use */
lib.string.lcFirst(myString);

titleCase

Returns the string in title case.

Context Signature
instance titleCase() → {String}
static titleCase({String} myString) → {String}
var myString   = 'the quick red fox jumped over the lazy brown dog!',
    titleCased = myString._.titleCase();

// titleCased = 'The Quick Red Fox Jumped Over The Lazy Brown Dog!'

/* Static Use */
lib.string.titleCase(myString);

splice

Splices a string, like Array.splice.

Context Signature
instance splice({Number} index, {Number} delete, {String=} append) → {String}
static splice({String} myString, {Number} index, {Number} delete, {String=} append) → {String}
var myString = 'the quick red fox jumped over the lazy brown dog!';
myString = myString._.splice(4, 5, 'slow');

// myString = 'the slow red fox jumped over the lazy brown dog!'

var helloWorld = 'hello world';
helloWorld._.splice(0, 6); // -> 'world'
helloWorld._.splice(5, 6); // -> 'hello'

/* Static Use */
lib.string.splice(myString, index, deleteCount, stringToAppendAtIndex);

ellipses

Truncates a string, adding ellipses if the string is longer than length.
Truncates the given string to length. If the string is longer than length, ellipses will be added to the end of the string.

  • If the optional place argument is set to 'front', the ellipses is prepended to the string, rather than appended.
  • The optional ellipses argument allows '...' to be replaces with any string value.
Context Signature
instance ellipses({Number} length, {String=} [place='back'], {String=} ellipses) → {String}
static ellipses({String} myString, {Number} length, {String=} place, {String=} ellipses) → {String}
var myString = 'the quick red fox jumped over the lazy brown dog!';

myString._.ellipses(10); // -> 'the qui...'
myString._.ellipses(20); // -> 'the quick red fox...'

myString._.ellipses(20, 'front');          // -> '...the quick red fox'
myString._.ellipses(20, 'front', '•••');   // -> '•••the quick red fox'
myString._.ellipses(20, 'back', '??????'); // -> 'the quick red ??????'

/* Static Use */
lib.string.splice(myString, index, deleteCount, stringToAppendAtIndex);

shuffle

Shuffles a string.
If the optional splitter argument is passed, it will be tokenized by the value of splitter before being shuffled. Otherwise the strings characters will be moved around.

Context Signature
instance shuffle({String=} splitter) → {String}
static shuffle({String} myString, {String=} splitter) → {String}
var aString = 'hello world';
aString._.shuffle() // -> 'lweol rhold' (this is one possibility)

'hello world'._.shuffle('hello ');
// Possibilities are...
// 'hello world', and 'worldhello '

'hello world'._.shuffle(' ');
// Possibilities are...
// 'hello world', 'world hello', 'worldhello ', ' helloworld'
// ' worldhello', and 'helloworld '

/* Static Use */
lib.string.shuffle(myString, splitter);

reverse

Reverses a string.

Context Signature
instance reverse() → {String}
static reverse({String} myString) → {String}
var myString = 'hello world';
myString._.reverse()  // -> 'dlrow olleh';
'racecar'._.reverse() // -> 'racecar'

/* Static Use */
lib.string.reverse(myString);

withoutTrailingSlash

Removes a trailing slash from a string (or path).
On Node.js withoutTrailingSlash uses path.sep for a platform agnostic replacement.

Context Signature
instance withoutTrailingSlash() → {String}
static withoutTrailingSlash({String} myString) → {String}
var path = 'path/to/some/directory/';
path._.withoutTrailingSlash() // -> 'path/to/some/directory'

path = 'path/to/some/directory/////';
path._.withoutTrailingSlash() // -> 'path/to/some/directory'

path = '/';
path._.withoutTrailingSlash() // -> ''

// If Node.js and Windows...
path = 'path\\to\\some\\directory\\';
path._.withoutTrailingSlash() // -> 'path\\to\\some\\directory'

/* Static Use */
lib.string.withoutTrailingSlash(myString);

withTrailingSlash

Removes a trailing slash from a string (or path).
On Node.js withoutTrailingSlash uses path.sep for a platform agnostic replacement.

Context Signature
instance withTrailingSlash() → {String}
static withTrailingSlash({String} myString) → {String}
var path = 'path/to/some/directory';
path._.withTrailingSlash() // -> 'path/to/some/directory/'

// If Node.js and Windows...
path = 'path\\to\\some\\directory';
path._.withoutTrailingSlash() // -> 'path\\to\\some\\directory\\'

/* Static Use */
lib.string.withTrailingSlash(myString);

regexpSafe

Returns a regular expression safe string.
Prepends slashes to /[-\/\\^$*+?.()|[\]{}]/g

Context Signature
instance regexpSafe() → {String}
static regexpSafe({String} myString) → {String}
var money  = '$1,000.00',
    badRegExp, safeRegexp, result;

badRegexp = new RegExp(money, 'gi');
result = '$1,000.00 dollars would be nice.'._.replace(badRegexp, 'One thousand dollars');
// -> Throws 'invalid regular expression'

safeRegexp = new RegExp(money._.regexpSafe(), 'gi');
result = '$1,000.00 dollars would be nice.'._.replace(badRegexp, 'One thousand dollars');
// -> 'One thousand dollars would be nice.'

/* Static Use */
lib.string.regexpSafe(myString);

pad

Pads a string (or truncates it) to the given length.
Prepends slashes to /[-\/\\^$*+?.()|[\]{}]/g

Context Signature
instance regexpSafe({String} length, {String=} [delimiter= ' '], {Boolean=} pre) → {String}
static regexpSafe({String} myString, {String} length, {String=} delimiter, {Boolean=} pre) → {String}
'hello world!'._.pad(3);  // -> 'hel'
'hello world!'._.pad(20); // -> 'hello world!        '

// Custom pad string
'hello world!'._.pad(3, '-');  // -> 'hel'
'hello world!'._.pad(20, '-'); // -> 'hello world!--------'

// If *pre* parameter is passed true...
'hello world!'._.pad(3, '-', true);  // -> 'ld!'
'hello world!'._.pad(20, '-', true); // -> '--------hello world!'

/* Static Use */
lib.string.pad(myString, length, delimiter, pre);

newlineToBreak

Replaces newlines with <br> tags.

Context Signature
instance newlineToBreak() → {String}
static newlineToBreak({String} myString) → {String}
'line 1\nline 2\nline 3'._.newlineToBreak();
// -> 'line 1<br>line 2<br>line 3'

/* Static Use */
lib.string.newlineToBreak(myString);

tabsToSpan

Replaces tab characters with tags.

Context Signature
instance tabsToSpan() → {String}
static tabsToSpan({String} myString) → {String}
'line 1\tline 2\tline 3'._.tabsToSpan();
// -> 'line 1<span class="tab"></span>line 2<span class="tab"></span>line 3'

/* Static Use */
lib.string.tabsToSpan(myString);

randomString

Generate a random string with the given length.
If the charPool argument isn't a string, the string below will be used:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSUVWXYZ_ `~!@#$%^&*()_+\\|][\';/.,|}{":?><

Context Signature
instance N/A
static randomString({Number=} [length=10], {String=} charPool) → {String}
libs.string.randomString(10);      // ew@64cvll- is one possibility
libs.string.randomString(2, 'aA'); // Possibilities: aa, aA, Aa, AA

Numbers

formatMoney

Formats a number as currency.

Context Signature
instance formatMoney({String=} [symbol='$']) → {String}
static formatMoney({Number} amount, {String=} [symbol='$']) → {String}
(1000)._.formatMoney();
// -> '$1,000.00'

(1234567.89)._.formatMoney();
// -> '$1,234,567.89'

(1000)._.formatMoney('£');
// -> '£1,000.00'

(1234567.89)._.formatMoney('£');
// -> '£1,234,567.89'

/* Static Use */
lib.string.formatMoney(amount, symbol);

withPlaceholders

Returns a string with the number separated by commas.

Context Signature
instance withPlaceholders() → {String}
static withPlaceholders({Number} myNumber) → {String}
(1000)._.withPlaceholders();
// -> '1,000'

(1234567.89)._.withPlaceholders();
// -> '1,234,567.89'

(1234567.8912)._.withPlaceholders();
// -> '1,234,567.8912'

/* Static Use */
lib.string.withPlaceholders(myNumber);

randomIntInRange

Get a random integer in the range [min, max] (inclusive)

Context Signature
instance N/A
static randomNumberInRange({Number} [a=0], {Number} [b=Number.MAX_VALUE]) → {Number}
lib.number.randomIntInRange(0, 100);    //-> Some integer between 0 and 100
lib.number.randomIntInRange(-100, 100); //-> Some integer between -100 and 100

randomNumberInRange

Get a random float in the range [min, max] (inclusive)

Context Signature
instance N/A
static randomNumberInRange({Number} [a=0], {Number} [b=Number.MAX_VALUE]) → {Number}
lib.number.randomNumberInRange(0.123, 100.784);    //-> Some integer between 0.123 and 100.784
lib.number.randomNumberInRange(-100.1, 5); //-> Some integer between -100.1 and 5

to

Gets a random integer/float using the number as the lower range and n as the upper range (both inclusive).
If n is omitted, Number.MAX_VALUE will be used. If the number is an integer, an integer will be returned; same for floats.

Context Signature
instance to() → {Number}
static N/A
(5)._.to(100);      // -> Some integer between 5 and 100
(5.1)._.to(100);    // -> Some float between 5.1 and 100
(-1)._.to(1)        // -> -1, 0, or 1
(-1.000001)._.to(1) // -> Some float value between -1.000001 to 1

factorial

Returns the factorial value of a number.
Any number greater than 170 returns Infinity (as the factorial of 171 > Number.MAX_VALUE). All negative numbers return NaN.

Context Signature
instance factorial() → {Number|Infinity}
static factorial({*} myNumber) → {Number|Infinity}
(3)._.factorial();   // -> 6
(0)._.factorial();   // -> 1
(100)._.factorial(); // -> ~9.332622e+157

(-1)._.factorial();  // -> NaN

/* Static Use */
lib.number.factorial(myNumber);

choose

Computes the number of combinations between n and k.

Context Signature
instance choose() → {Number|Infinity}
static choose({Number} n, {Number} k) → {Number|Infinity}
(3)._.choose(2);            // -> 3
(10000)._.choose(1);        // -> 1000
(10000)._.choose(10000);    // -> 1
(1000)._.choose(170);       // -> ~3.27184e+196

/* Static Use */
lib.number.choose(n, k);

isInt

True if all arguments are integers, false otherwise.
This method checks for a '.' using Number.toString, so any number with a period is considered a "float".

Context Signature
instance isInt() → {Boolean}
static isInt({...Number} n) → {Boolean}
(5)._.isInt()       // -> true
(5.123)._.isInt()   // -> false
(0)._.isInt()       // -> true
(5.0)._.isInt()     // -> false
(-1.2)._.isInt()    // -> false

/* Static Use */
lib.number.isInt(a, b, c, d, e...);

pad

Pads a number with leading zeros.
Returns a string representation of a number padded with leading or trailing zeros.

Context Signature
instance pad({Number} length) → {String}
static pad({Number} n, {Number} length) → {String}
(5)._.pad(3);  // -> 005
(50)._.pad(3); // -> 050

/* Static Use */
lib.number.pad(n, length);

daysFrom

Gets a date that occurs n days from the given date.

Context Signature
instance daysFrom({Date} date) → {Date}
static daysFrom({Number} n, {Date} date) → {Date}

hoursFrom

Gets a date that occurs n hours from the given date.

Context Signature
instance hoursFrom({Date} date) → {Date}
static hoursFrom({Number} n, {Date} date) → {Date}

minutesFrom

Gets a date that occurs n minutes from the given date.

Context Signature
instance minutesFrom({Date} date) → {Date}
static minutesFrom({Number} n, {Date} date) → {Date}

secondsFrom

Gets a date that occurs n seconds from the given date.

Context Signature
instance secondsFrom({Date} date) → {Date}
static secondsFrom({Number} n, {Date} date) → {Date}

yearsFrom

Gets a date that occurs n years from the given date.

Context Signature
instance yearsFrom({Date} date) → {Date}
static yearsFrom({Number} n, {Date} date) → {Date}

monthsFrom

Gets a date that occurs n month from the given date.

Context Signature
instance monthsFrom({Date} date) → {Date}
static monthsFrom({Number} n, {Date} date) → {Date}

daysFromNow

Gets a date that occurs n days from the current time.

Context Signature
instance daysFrom() → {Date}
static daysFrom({Number} n) → {Date}

secondsFromNow

Gets a date that occurs n seconds from the current time.

Context Signature
instance secondsFromNow() → {Date}
static secondsFromNow({Number} n) → {Date}

yearsFromNow

Gets a date that occurs n years from the current time.

Context Signature
instance yearsFromNow() → {Date}
static yearsFromNow({Number} n) → {Date}

monthsFromNow

Gets a date that occurs n months from the current time.

Context Signature
instance monthsFromNow() → {Date}
static monthsFromNow({Number} n) → {Date}

hoursFromNow

Gets a date that occurs n hours from the current time.

Context Signature
instance hoursFromNow() → {Date}
static hoursFromNow({Number} n) → {Date}

daysAgo

Gets a date that occurs n days before the current time.

Context Signature
instance daysAgo() → {Date}
static daysAgo({Number} n) → {Date}

secondsAgo

Gets a date that occurs n days before the current time.

Context Signature
instance secondsAgo() → {Date}
static secondsAgo({Number} n) → {Date}

minutesAgo

Gets a date that occurs n days before the current time.

Context Signature
instance minutesAgo() → {Date}
static minutesAgo({Number} n) → {Date}

yearsAgo

Gets a date that occurs n days before the current time.

Context Signature
instance yearsAgo() → {Date}
static yearsAgo({Number} n) → {Date}

monthsAgo

Gets a date that occurs n days before the current time.

Context Signature
instance monthsAgo() → {Date}
static monthsAgo({Number} n) → {Date}

Arrays

shuffle

Shuffles an arrays contents.

Context Signature
instance shuffle() → {Array}
static shuffle({Array} a) → {Array}
[1, 2, 3]._.shuffle(); // [3, 1, 2] is one possibility

/* Static Use */
lib.array.shuffle(n, length);

union

Returns a new array containing the unique union from the given arrays.
If you want the set union, use Array.concat

Context Signature
instance union({Array} a, {Array} b, {Array} c...) → {Array}
static union({Array} a, {Array} b, {Array} c...) → {Array}
[1, 2, 3]._.union([3, 4, 5, 6]);               // -> [1, 2, 3, 4, 5, 6]
[1, 2, 3]._.union([3, 4, 5, 6], [1, 7, 8, 9]); // -> [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* Static Use */
lib.array.union(arrayA, arrayB, arrayC...);

difference

Returns a new array the set difference from the given arrays.
That is, the objects that are unique to only one array.

Context Signature
instance difference({Array} a, {Array} b, {Array} c...) → {Array}
static difference({Array} a, {Array} b, {Array} c...) → {Array}
[1, 2, 3]._.difference([3, 4, 5, 6]);                      // -> [1, 2, 4, 5, 6]
[1, 2, 3]._.difference([3, 4, 5, 6], [1, 7, 8, 9], ['a']); // -> [2, 4, 5, 6, 7, 8, 9, 'a']

[2, 2, 2, 1]._.difference([3, 3, 3, 1], [1]); // -> [2, 2, 2, 3, 3, 3]
[2, 2, 1, 1]._.difference([3, 3, 1, 1], [1]); // -> [2, 2, 3, 3]

/* Static Use */
lib.array.difference(arrayA, arrayB, arrayC...);

intersect

Returns a new array the set intersection from the given arrays.
That is, the objects that are contained in all the arrays.

Context Signature
instance intersect({Array} a, {Array} b, {Array} c...) → {Array}
static intersect({Array} a, {Array} b, {Array} c...) → {Array}
[1, 2, 3]._.intersect([3, 4, 5, 6]);                            // -> [3]
[1, 2, 3]._.intersect([3, 4, 5, 6], [1, 7, 8, 9], ['a']);       // -> []
[1, 2, 3]._.intersect([3, 4, 5, 6], [1, 3, 7, 8, 9], ['a']);    // -> []
[1, 2, 3]._.intersect([3, 4, 5, 6], [1, 3, 7, 8, 9], ['a', 3]); // -> [3]

/* Static Use */
lib.array.intersect(arrayA, arrayB, arrayC...);

without

Returns a new array without the given objects.

Context Signature
instance without({*} objA, {*} objA, {*} objA...) → {Array}
static without({Array} arrayToFilter, {*} objA, {*} objB...) → {Array}
[1, 2, 3]._.without(2, 3);      // -> [1]
['a', 'b', 'c']._.without('e'); // -> ['a', 'b', 'c']

var obj = { foo: 'bar' };

[obj, 1, 'a string', obj, obj]._.without(obj); // -> [1, 'a string']

/* Static Use */
lib.array.without(arrayToFilter, objA, objB...);

rotate

Rotates an array's contents left or right.
This is useful for circular array data structures.
Modifies the original array!

Context Signature
instance rotate({String=} [direction='left'], {Number=} [amount=1]) → {Array}
static rotate({Array} arrayToRotate, {String=} [direction='left'], {Number=} [amount=1]) → {Array}
[1, 2, 3]._.rotate('left', 1); // -> [2, 3, 1]
[1, 2, 3]._.rotate('right');   // -> [3, 1, 2]

[1, 2, 3]._.rotate('left', 1); // -> [2, 3, 1]
[1, 2, 3]._.rotate('left', 2); // -> [3, 1, 2]
[1, 2, 3]._.rotate('left', 3); // -> [1, 2, 3]
[1, 2, 3]._.rotate('left', 4); // -> [2, 3, 1]

// Since it modifies the array,
// the following *might* not be expected
var array = [1, 2, 3];
array._.rotate('left', 1); // -> [2, 3, 1]
array._.rotate('left', 2); // -> [1, 2, 3]
array._.rotate('left', 3); // -> [1, 2, 3]
array._.rotate('left', 4); // -> [2, 3, 1]

/* Static Use */
lib.array.rotate(arrayToRotate, direction, amount);

rotateLeft

Rotates an array's contents left.
Functions just like rotate. Modifies the original array!

Context Signature
instance rotateLeft({Number=} [amount=1]) → {Array}
static rotateLeft({Array} arrayToRotate, {Number=} [amount=1]) → {Array}

rotateRight

Rotates an array's contents left.
Functions just like rotate. Modifies the original array!

Context Signature
instance rotateRight({Number=} [amount=1]) → {Array}
static rotateRight({Array} arrayToRotate, {Number=} [amount=1]) → {Array}

makeUnique

Removes duplicates from the current array.
Modifies the original array!

Context Signature
instance makeUnique() → {Array}
static makeUnique({Array} arrayToModify) → {Array}
var arr = [1, 2, 3, 3, 4];
arr._.makeUnique(); // arr = [1, 2, 3, 4]

var objA = { foo: 'bar' },
    objB = { foo: 'bar' };

arr = [objA, objB, objA];
arr._.makeUnique() // arr = [objA, objB]

/* Static Use */
lib.array.makeUnique(arrayToModify);

unique

Returns a new array with the unique items from the given array.
Same as makeUnique, but does not modify the original array.

Context Signature
instance unique() → {Array}
static unique({Array} array) → {Array}

ascending

Sorts the array in ascending order.

Context Signature
instance ascending() → {Array}
static ascending({Array} array) → {Array}

descending

Sorts the array in descending order.

Context Signature
instance descending() → {Array}
static descending({Array} array) → {Array}

Functions

inherits

Inherit the prototype methods from one constructor into another.
In addition, a super_ property will be added to the inheriting class, which references the super constructor.

Context Signature
instance inherit({Function} superConstructor) → {Function}
static inherit({Function} inheritingConstructor, {Function} superConstructor) → {Function}
// Inherit the prototype methods from Array
var MyClass = function () { ... };
MyClass._.inherits(Array);

var Dog = function () {};
Dog.prototype.speak = function () {
    return 'Bark!';
};

var BlackDog = function () {
    this.color = 'black';
};

var dog = new BlackDog();
dog._.inherits(Dog);
dog.speak(); // Returns 'Bark!';

/* Static Use */
lib.function.inherits(inheritingConstructor, superConstructor);

Dates

advanceDays

Advances the date the given number of days.
If adjustForWeeked is evaluates to true and the date falls on a weekend, it will be fast forwarded to Monday.
Modifies the given date!

Context Signature
instance advanceDays({Number} numberOfDays, {Boolean=} adjustForWeekend) → {Date}
static advanceDays({Date} dateToModify, {Number} days, {Boolean=} adjustForWeekend) → {Date}
var date = new Date();
date._.advanceDays(5); // Advances the date 5 days ahead

/* Static Use */
lib.date.advanceDays(dateToModify, numberOfDays, adjustForWeekend);

advanceMonths

Advances the date the given number of months.
If adjustForWeeked is evaluates to true and the date falls on a weekend, it will be fast forwarded to Monday.
Modifies the given date!

Context Signature
instance advanceMonths({Number} numberOfMonths, {Boolean=} adjustForWeekend) → {Date}
static advanceMonths({Date} dateToModify, {Number} numberOfMonths, {Boolean=} adjustForWeekend) → {Date}
var date = new Date();
date._.advanceMonths(3); // Advances the date 3 months ahead

/* Static Use */
lib.date.advanceMonths(dateToModify, numberOfMonths, adjustForWeekend);

advanceYears

Advances the date the given number of years.
If adjustForWeeked is evaluates to true and the date falls on a weekend, it will be fast forwarded to Monday.
Modifies the given date!

Context Signature
instance advanceYears({Number} numberOfYears, {Boolean=} adjustForWeekend) → {Date}
static advanceYears({Date} dateToModify, {Number} numberOfYoears, {Boolean=} adjustForWeekend) → {Date}
var date = new Date();
date._.advanceYears(3); // Advances the date 3 years ahead

/* Static Use */
lib.date.advanceYears(dateToModify, numberOfYears, adjustForWeekend);

yyyymmdd

Returns a string from a Date object in the YYYY-MM-DD format.
If separator is set to a string, it will be used instead of '-'.

Context Signature
instance yyymmdd({String=} separator) → {String}
static yyymmdd({Date} dateObject, {String=} separator) → {String}
var date = new Date('4/28/2016');
date._.yyyymmdd();    // -> '2016-04-28'
date._.yyyymmdd('.'); // -> '2016.04.28'

/* Static Use */
lib.date.yyyymmdd(dateObject, separator);

clockTime

Returns a string from a Date object in the format HH:MM:SS.MSEC.
If omitMS is true, the millisecond portion of the string will be omitted.

Context Signature
instance clockTime({Boolean=} omitMS) → {String}
static clockTime({Date} dateObject, {Boolean=} omitMS) → {String}
var date = new Date('4/26/2016 8:32:00 GMT-0400');
date._.clockTime(); // -> '20:32:00.00'

date = new Date('4/26/2016 8:32:15 GMT-0400');
date._.clockTime(true); // -> '20:32:15'

/* Static Use */
lib.date.clockTime(dateObject, omitMS);

Extending ProtoLib


Adding Methods

You can add your own utility methods to a ProtoLib instance by using ProtoLib#extend...

ProtoLib#extend({Function=} [constructor=Object], {String} name, {String=} staticNamepace, {Function} method) → {Boolean}

Adds a method to the given constructor and all inheritors of the constructor.
Returns true if successful, false otherwise.

The new method will be available both statically and as a member on instance libraries. You should write your methods statically. That is, you should include the object as the first argument to the method. Objects calling the instance version of the method will adjust for this automagically, and use the arguments 1-n provided in the method callback; that is: with the first argument omitted.

Example: Adding a method to all Array objects...

var lib = ProtoLib.get('_');

// Example: add a method to String to console.log the string...
var wasExtended = lib.extend(String, 'log', function (str) {
    console.log(str);
});

'Hello World'._.log();
// Console logs 'Hello World!'

lib.string.log('Hello world, Static Version!');
// Console logs 'Hello world, Static Version!'

// Example: write a method to remove all objects from an array,
// except for the first n...

var wasExtended = lib.extend(Array, 'empty', function (array, leaveFirstN) {
    leaveFirstN = typeof leaveFirstN === 'number' ? leaveFirstN : 0;
    // this refers to object being operated on when using ProtoLib#extend
    // So, this === array
    for(var i = leaveFirstN; i < this.length; i++) {
        this.splice(i, 1);
        // We have to adjust our array pointer here,
        // since splice modifies the array internally.
        i--;
    }
    return this;
});

var [1, 2, 3]._.empty();  // -> []
var [1, 2, 3]._.empty(2); // -> [1, 2]

// For the record, it's typically faster to assign an array
// to a new array, than empty it.
Extended Static Versions

The static version of an extended method will be added to lib[staticNamespace] and lib.my where lib is the reference to a ProtoLib instance and staticNamespace is the 3rd argument of Protolib#extend. So calling Protolib#extend with:

lib.extend(MyClass, 'methodName', 'MyClass', someFunction);

Will result in the following static methods...

lib.MyClass.methodName
lib.my.methodName

If staticNamespace is omitted... ProtoLib will add the method to the my static namespace, and if the constructor function has a name, it will use the constructor name. Note, Internet Explorer doesn't support Function.name, so for IE the following is not true.

var MyClass = function myClassConstructor () { ... }
lib.extend(MyClass, 'example', someFunction);

lib.myClassConstructor.example
lib.my.example

// In IE only lib.my.example is available...

If the constructor is a built-in type (i.e. Object, Array, Date, Number, String, Error, Function, RegExp, etc.), the staticNamepace argument will be ignored and the lowercased version of the constructor name will be used. For example:

var MyClass = function myClassConstructor () { ... }
lib.extend(Array, 'example', 'myStaticNamepace' someFunction);

// 'example' function will be added to the following static namespaces...
lib.array.example
lib.my.example

// It will *not* be added to:
lib.myStaticNamepace.example

Deleting Methods

You can delete utility methods from a ProtoLib instance by using ProtoLib#delete...

ProtoLib#delete({Function} constructor, {String} name) → {Boolean}

Deletes a library method from the ProtoLib instance for the given constructor.
Returns true if successful, false otherwise.

var lib = ProtoLib.get('_');
var MyClass = function () {};

// Add a new library method...
lib.extend(MyClass, 'example', myObject => {
    console.log('Example called!');
});

var myClassObject = new MyClass();
myClassObject._.example(); // Logs 'Example called!'

// Delete the library method...
var wasDeleted = lib.delete(MyClass, 'example');
myClassObject._.example(); // TypeError: myClassObject._.example is not a function

Advanced


This section is basically informational.
You probably won't ever use it, but it's here just in case.

Instance Methods

ProtoLib#load → {ProtoLib}

Adds the library (handle) object to all objects.
Returns a reference to the current ProtoLib instance.

ProtoLib#unload → {ProtoLib}

Removes the handle object from all objects.
Returns a reference to the current ProtoLib instance.

ProtoLib#killCache({Function=} constr) → {ProtoLib}

Kills the library cache, forcing handle objects to be recreated on the next call.
If a Function is passed in for parameter constr, only the given constructor's cache will be deleted. Returns a reference to the current ProtoLib instance.

ProtoLib#setHandle() → {ProtoLib}

Resets the handle, for accessing the library.
Returns a reference to the current ProtoLib instance.

var lib = ProtoLib.get('_');

'example'._.reverse();  // -> 'elpmaxe'

lib.setHandle('pl');

'example'._.reverse();  // TypeError: 'example'._.reverse is not a function
'example'.pl.reverse(); // -> 'elpmaxe'

ProtoLib#extend({Function=} [constructor=Object], {String} name, {String=} staticNamepace, {Function} method) → {Boolean}

See Adding Methods

ProtoLib#delete({Function} constructor, {String} name) → {Boolean}

See Deleting Methods

Static Methods

ProtoLib.get({String} handle) → {ProtoLib} instance

Retrieves the ProtoLib instance with the given handle, or creates a new one.

ProtoLib.killCache({String=} handle) → {Function} ProtoLib

Kills the cache for the ProtoLib instance with the given handle
If no handle is specified, all ProtoLib instances will have their cache cleared.

ProtoLib.killCacheForConstructor({String=} constr) → {Function} ProtoLib

Kills the cache for the given constructor for all ProtoLib instances.
If no constructor is specified, or if constr isn't a function, no action will be taken.

ProtoLib.destroy({String} handle) → {Function} ProtoLib

Destroys a ProtoLib instance, and removes it's library methods from all objects
This also frees up the ProtoLib instance with the given handle to be garbage collected, if not referenced elsewhere.

About

The namespace friendly prototype library for both node and browsers.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published