2016-11-04 13:45:51 -04:00
|
|
|
/**
|
|
|
|
* @file obj.js
|
2016-12-02 15:17:08 -05:00
|
|
|
* @module obj
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @callback obj:EachCallback
|
|
|
|
*
|
|
|
|
* @param {Mixed} value
|
|
|
|
* The current key for the object that is being iterated over.
|
|
|
|
*
|
|
|
|
* @param {string} key
|
|
|
|
* The current key-value for object that is being iterated over
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @callback obj:ReduceCallback
|
|
|
|
*
|
|
|
|
* @param {Mixed} accum
|
|
|
|
* The value that is accumulating over the reduce loop.
|
|
|
|
*
|
|
|
|
* @param {Mixed} value
|
|
|
|
* The current key for the object that is being iterated over.
|
|
|
|
*
|
|
|
|
* @param {string} key
|
|
|
|
* The current key-value for object that is being iterated over
|
|
|
|
*
|
|
|
|
* @return {Mixed}
|
|
|
|
* The new accumulated value.
|
2016-11-04 13:45:51 -04:00
|
|
|
*/
|
2016-12-02 15:44:57 -05:00
|
|
|
const toString = Object.prototype.toString;
|
2016-11-04 13:45:51 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Array-like iteration for objects.
|
|
|
|
*
|
2016-12-02 15:17:08 -05:00
|
|
|
* @param {Object} object
|
|
|
|
* The object to iterate over
|
|
|
|
*
|
|
|
|
* @param {obj:EachCallback} fn
|
|
|
|
* The callback function which is called for each key in the object.
|
2016-11-04 13:45:51 -04:00
|
|
|
*/
|
|
|
|
export function each(object, fn) {
|
|
|
|
Object.keys(object).forEach(key => fn(object[key], key));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Array-like reduce for objects.
|
|
|
|
*
|
2016-12-02 15:17:08 -05:00
|
|
|
* @param {Object} object
|
|
|
|
* The Object that you want to reduce.
|
|
|
|
*
|
|
|
|
* @param {Function} fn
|
2016-11-04 13:45:51 -04:00
|
|
|
* A callback function which is called for each key in the object. It
|
|
|
|
* receives the accumulated value and the per-iteration value and key
|
|
|
|
* as arguments.
|
2016-12-02 15:17:08 -05:00
|
|
|
*
|
|
|
|
* @param {Mixed} [initial = 0]
|
|
|
|
* Starting value
|
|
|
|
*
|
2016-11-04 13:45:51 -04:00
|
|
|
* @return {Mixed}
|
2016-12-02 15:17:08 -05:00
|
|
|
* The final accumulated value.
|
2016-11-04 13:45:51 -04:00
|
|
|
*/
|
|
|
|
export function reduce(object, fn, initial = 0) {
|
|
|
|
return Object.keys(object).reduce(
|
2016-12-02 15:17:08 -05:00
|
|
|
(accum, key) => fn(accum, object[key], key), initial);
|
2016-11-04 13:45:51 -04:00
|
|
|
}
|
2016-12-02 15:44:57 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Object.assign-style object shallow merge/extend.
|
|
|
|
*
|
|
|
|
* @param {Object} target
|
|
|
|
* @param {Object} ...sources
|
|
|
|
* @return {Object}
|
|
|
|
*/
|
|
|
|
export function assign(target, ...sources) {
|
|
|
|
if (Object.assign) {
|
|
|
|
return Object.assign(target, ...sources);
|
|
|
|
}
|
|
|
|
|
|
|
|
sources.forEach(source => {
|
|
|
|
if (!source) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
each(source, (value, key) => {
|
|
|
|
target[key] = value;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
return target;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether a value is an object of any kind - including DOM nodes,
|
|
|
|
* arrays, regular expressions, etc. Not functions, though.
|
|
|
|
*
|
|
|
|
* This avoids the gotcha where using `typeof` on a `null` value
|
|
|
|
* results in `'object'`.
|
|
|
|
*
|
|
|
|
* @param {Object} value
|
|
|
|
* @return {Boolean}
|
|
|
|
*/
|
|
|
|
export function isObject(value) {
|
|
|
|
return !!value && typeof value === 'object';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether an object appears to be a "plain" object - that is, a
|
|
|
|
* direct instance of `Object`.
|
|
|
|
*
|
|
|
|
* @param {Object} value
|
|
|
|
* @return {Boolean}
|
|
|
|
*/
|
|
|
|
export function isPlain(value) {
|
|
|
|
return isObject(value) &&
|
|
|
|
toString.call(value) === '[object Object]' &&
|
|
|
|
value.constructor === Object;
|
|
|
|
}
|