smart-extend
smart-extend
is an extension to jQuery's classic extend()
method with additional features providing you with more power and control over your object extensions/clones. Works in both Node.JS and the browser.
Highlights
- Deep/shallow object cloning/extension.
- Optional array concatination.
- Optionally copy only 'own' properties.
- Specify specific properties to copy.
- Apply filter functions to allow only specific properties/values to be copied.
- Expressive API.
- Clean, Focused, and actively maintained.
Table of Contents
Example Usage
var extend = ;var objA = a:1 b:2;var objB = b:3 c:4;var objC = a:1 b:2 inner:a:1 b:2;var objD = b:3 c:4 inner:b:3 c:4;var emptyObj = {}; // Copy objA into emptyObj //-> emptyObj === {a:1, b:2} // Copy objA & objB into emptyObj //-> emptyObj === {a:1, b:3, c:4} // Shallow Copy objC & objD into a new object //-> {a:1, b:3, c:4, inner:{b:3, c:4}} // Deep Copy objC & objD into a new objectextend //-> {a:1, b:3, c:4, inner:{a:1, b:3, c:4}} // Clone objA (without specifying a target)extend //-> {a:1, b:2} // Clone objA with only property 'a'extendcloneobjA //-> {a:1} // Clone objC with properties named 'a' or 'inner'extendcloneobjC //-> {a:1, inner:{a:1}} // Copy objA's & objB's properties that have a value greater than 2extend{} objA objB //-> {b:3, c:4} // Concat array values //-> {arr: [4,5,6]}extend //-> {arr: [1,2,3,4,5,6]} // And more...
Usage
extend(target, object1[, objectN...])
Shallow copy all properties (own & inherited) of object1
and any following objects into target
.
extend[.<option>[.<option>...]](...)
Perform copy/extension with the specified options. options
can be chained in any desired order and some accept arguments.
Example:
extend.keys(['a', 'b']).clone.deep(targetObject)
will deep clone targetObject
's 'a'
and 'b'
properties.
Options
own
Only copies 'own' properties of object and not inherited properties.
Example:
var {thisa = 1; thisb = 2;}SomeConstructorprototypeinherited = 'abc'var object = ; //-> {a:1, b:2, inherited:'abc'}extend //-> {a:1, b:2}
deep
Performs a recursive copy of the specified objects.
Example:
var objA = a:1 b:2 inner:a:1 b:2;var objB = b:3 c:4 inner:b:3 c:4;var cloneA = ;var cloneB = extend; cloneA === objA //-> falsecloneAinner === objAinner //-> truecloneBinner === objAinner //-> false //-> {a:1, b:3, c:4, inner:{b:3, c:4}}extend //-> {a:1, b:3, c:4, inner:{a:1, b:3, c:4}}
notDeep(array|object)
When paired with .deep
it performs a recursive copy of the specified objects while performing a shallow copy for the provided keys.
Example:
var objA = one:a:1 b:2 two:a:1 b:2;var objB = one:b:3 c:4 two:b:3 c:4;var clone = extenddeep{} objA objB; cloneone === objBone //-> falseclonetwo === objBtwo //-> trueclone //-> {one:{a:1, b:3, c:4}, two:{b:3, c:4}};
deepOnly(array|object)
When paired with .deep
it performs a recursive copy of the specified objects while performing a shallow copy for the provided keys.
Example:
var objA = one:a:1 b:2 two:a:1 b:2;var objB = one:b:3 c:4 two:b:3 c:4;var clone = extenddeep{} objA objB; cloneone === objBone //-> trueclonetwo === objBtwo //-> falseclone //-> {one:{b:3, c:4}, two:{a:1, b:3, c:4}};
allowNull
Allows null
values to be copied over.
Example:
var object = a:1 b:null c:3; //-> {a:1, c:3}extend //-> {a:1, b:null, c:3}
nullDeletes
Encounters of null
values in the source object will delete/remove the associated key in the target object.
Example:
var object = nested:a:1 b:2 c:3 c:3;var deletes = nesteda:10 c:null; //-> {nested:{a:10}, c:3}extend //-> {nested:{a:10}}extendnullDeletes //-> {nested:{a:10, b:2, c:3}}
clone
Clone the specified objects without specifying a target. This is basically a shortcut in which instead of passing an empty object as the first argument (i.e. the target object), an empty object will be created internally for you.
Example:
// Both will render the same resultsvar A = //-> {a:1, b:2}var B = extend //-> {a:1, b:2}
concat
Causes array properties to be merged/concatenated instead of the usual behavior in which the 2nd array replaces the first. Behaves the same in both deep & shallow copies.
Example:
var objA = arr: 123;var objB = arr: 456;var objB2 = arr: null456; //-> {arr: [4,5,6]}extend //-> {arr: [1,2,3,4,5,6]} //-> {arr: [null,4,5,6]}extend //-> {arr: [1,4,5,6]}extenddeep //-> {arr: [1,2,3,4,5,6]}
keys(array|object)
Allows only properties whose name is included in the provided array. If a plain object is passed its keys/property names will be extracted into an array (disregarding the property values).
Example:
var objA = a:1 b:2;var objB = b:3 c:4 d:5; //-> {a:1, b:3, c:4, d:5}extend{} objA objB //-> {a:1, c:4}extend{} objA objB //-> {b:3, d:5}
notKeys(array|object)
Same as keys
, but instead excludes and keys matching the one of the keys provided in the array/object.
Example:
var objA = a:1 b:2;var objB = b:3 c:4 d:5; //-> {a:1, b:3, c:4, d:5}extend{} objA objB //-> {a:1, c:4}extend{} objA objB //-> {b:3, d:5}
transform(transformFunction|transformMap)
Runs the provided transformFunction
on each property encoutered in the provided sources with the following arguments: transformFunction(value, key, source)
. The value returned from the transformFunction
will be used instead of the original value regardless if the transformed value is equal to undefined
, null
, or anything else. If provided a filter, transforms will be invoked only for properties that passed the filter predicate.
A transformMap
object can be passed instead of a single function which is an object with the signature of {property: transformFunction}
. When iterating through the source's properties, if there is a function predicate matching the currently processed property's name then it will be invoked and treated like a filterFunction
.
Arguments:
transformFunction
- a transform function to apply to each property encoutered in the source objects (i.e. the objects we are extending/copying).value
- The value of the current property being processed in the object.key
- The the name (or label) of the current property being processed in the object.source
- The object which this property belongs to.
Example (transformFunction):
var objA = a:'a1' b:'b2';var objB = b:'b3' c:'c4';var {return value} extend{} objA objB //-> {a:'A1', b:'B3', c:'C4'}
Example (transformMap):
var objA = a:'a1' b:'b2';var objB = b:'b3' c:'c4'; extend{} objA objB//-> {a:'A1', b:'b3', c:'C4!'}
filter(filterFunction|filterMap)
Runs the provided filterFunction
on each property encoutered in the provided sources with the following arguments: filterFunction(value, key, source)
. The value returned from the filterFunction
will be used to determine whether or not to copy the subject property - if the value is a truthy value the value property will be copied and if the value is a falsey value it will be omitted.
A filterMap
object can be passed instead of a single function which is an object with the signature of {property: filterFunction}
. When iterating through the source's properties, if there is a function predicate matching the currently processed property's name then it will be invoked and treated like a filterFunction
.
Arguments:
filterFunction
- a filter predicate to apply to each property encoutered. Returntrue
to copy the property, otherwise returnfalse
to not copy the property.value
- The value of the current property being processed in the object.key
- The the name (or label) of the current property being processed in the object.source
- The object which this property belongs to.
Example (filterFunction):
var objA = a:1 b:10;var objB = b:3 c:4 d:5;var {return value > 3}; extend{} objA objB //-> {b:10, c:4, d:5}
Example (filterMap):
var objA = a:1 b:5 c:3;var objB = a:3 b:2 c:5 e:0;var objC = a:10 b:'20' c:30 d:40; extendobjA objB objC//-> {a:1, b:'20', c:5, d:40}
License
MIT © Daniel Kalen