Skip to content

Instantly share code, notes, and snippets.

@dalgard
Created April 26, 2014 15:24
Show Gist options
  • Save dalgard/11322812 to your computer and use it in GitHub Desktop.
Save dalgard/11322812 to your computer and use it in GitHub Desktop.
Method for deep (recursive) extension of a given object with the properties of passed-in object(s) with support for standards-compliant getters and setters
function extendDeep(target) {
// Run through rest parameters
Array.prototype.slice.call(arguments, 1).forEach(function (source) {
if (typeof target === "object") {
if (typeof source === "object") {
// If source is an array, only copy enumerable properties
var keys = (Array.isArray(source) ? Object.keys(source) : Object.getOwnPropertyNames(source));
// Iterate over keys
keys.forEach(function (key) {
// Standards-compliant awesomeness
var target_descriptor = Object.getOwnPropertyDescriptor(target, key),
source_descriptor = Object.getOwnPropertyDescriptor(source, key);
if (typeof source_descriptor.value === "object") {
if (!target_descriptor || typeof target_descriptor.value !== "object") {
target[key] = (Array.isArray(source_descriptor.value) ? [] : {});
}
// Recursion
extendDeep(target[key], source[key]);
}
else if (source_descriptor.value || source_descriptor.get || source_descriptor.set) {
Object.defineProperty(target, key, source_descriptor);
}
});
}
}
else if (typeof source !== "undefined") {
// If target is not an object, simply set it to source
target = source;
}
});
return target;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment