lib/object.js
function (obj, options) {
        var instance = this,
            i = -1,
            deepForce, keys, l, key, force, replace, descriptors, propDescriptor;
        if (!Object.itsa_isObject(obj)) {
            return instance;
        }
        options || (options={});
        keys = options.full ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
        l = keys.length;
        force = options.force;
        deepForce = (force==="deep");
        replace = options.replace;
        descriptors = options.descriptors;
        // we cannot use obj.each --> obj might be an object defined through Object.create(null) and missing Object.prototype!
        while (++i < l) {
            key = keys[i];
            if ((force && !replace) || (!replace && !(key in instance)) || (replace && (key in instance))) {
                if (deepForce && Object.itsa_isObject(instance[key]) && Object.itsa_isObject(obj[key])) {
                    instance[key].itsa_merge(obj[key], options);
                }
                else {
                    if (descriptors) {
                        propDescriptor = Object.getOwnPropertyDescriptor(obj, key);
                        if (!propDescriptor.writable) {
                            instance[key] = obj[key];
                        }
                        else {
                            Object.defineProperty(instance, key, propDescriptor);
                        }
                    }
                    else {
                        instance[key] = obj[key];
                    }
                }
            }
        }
        return instance;
    }
function (obj, options) {
        var instance = this,
            i = -1,
            deepForce, keys, l, key, force, replace, descriptors, propDescriptor;
        if (!Object.itsa_isObject(obj)) {
            return instance;
        }
        options || (options={});
        keys = options.full ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
        l = keys.length;
        force = options.force;
        deepForce = (force==="deep");
        replace = options.replace;
        descriptors = options.descriptors;
        // we cannot use obj.each --> obj might be an object defined through Object.create(null) and missing Object.prototype!
        while (++i < l) {
            key = keys[i];
            if ((force && !replace) || (!replace && !(key in instance)) || (replace && (key in instance))) {
                if (deepForce && Object.itsa_isObject(instance[key]) && Object.itsa_isObject(obj[key])) {
                    instance[key].itsa_merge(obj[key], options);
                }
                else {
                    if (descriptors) {
                        propDescriptor = Object.getOwnPropertyDescriptor(obj, key);
                        if (!propDescriptor.writable) {
                            instance[key] = obj[key];
                        }
                        else {
                            Object.defineProperty(instance, key, propDescriptor);
                        }
                    }
                    else {
                        instance[key] = obj[key];
                    }
                }
            }
        }
        return instance;
    }
function ( obj , options ) { var instance = this , i = - 1 , deepForce , keys , l , key , force , replace , descriptors , propDescriptor ; if ( ! Object . itsa_isObject ( obj ) ) { return instance ; } options || ( options = { } ) ; keys = options . full ? Object . getOwnPropertyNames ( obj ) : Object . keys ( obj ) ; l = keys . length ; force = options . force ; deepForce = ( force === "deep" ) ; replace = options . replace ; descriptors = options . descriptors ; // we cannot use obj.each --> obj might be an object defined through Object.create(null) and missing Object.prototype! while ( ++ i < l ) { key = keys [ i ] ; if ( ( force && ! replace ) || ( ! replace && ! ( key in instance ) ) || ( replace && ( key in instance ) ) ) { if ( deepForce && Object . itsa_isObject ( instance [ key ] ) && Object . itsa_isObject ( obj [ key ] ) ) { instance [ key ] . itsa_merge ( obj [ key ] , options ) ; } else { if ( descriptors ) { propDescriptor = Object . getOwnPropertyDescriptor ( obj , key ) ; if ( ! propDescriptor . writable ) { instance [ key ] = obj [ key ] ; } else { Object . defineProperty ( instance , key , propDescriptor ) ; } } else { instance [ key ] = obj [ key ] ; } } } } return instance ; }
Merges into this object the properties of the given object.
If the second argument is true, the properties on the source object will be overwritten
by those of the second object of the same name, otherwise, they are preserved.

@method itsa_merge
@param obj {Object} Object with the properties to be added to the original object
@param [options] {Object}
@param [options.force=false] {Boolean|'deep'}
true ==> the properties in `obj` will override those of the same name in the original object
false ==> the properties in `obj` will NOT be set if the name already exists in the original object
'deep' ==> the properties in `obj` will completely be deep-merged with the original object: both deep-proerties will endure. When
both `obj` and the original object have the same `simple-type`-property, the `obj` its proerty will be used
@param [options.full=false] {Boolean} If true, also any non-enumerable properties will be merged
@param [options.replace=false] {Boolean} If true, only properties that already exist on the instance will be merged (forced replaced). No need to set force as well.
@param [options.descriptors=false] {Boolean} If true, the full descriptors will be set. This takes more time, but avoids any info to be lost.
@chainable
Merges into this object the properties of the given object . If the second argument is true the properties on the source object will be overwritten by those of the second object of the same name otherwise they are preserved .