Skip to content

Instantly share code, notes, and snippets.

@z5h
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save z5h/504f4cce5672f918901e to your computer and use it in GitHub Desktop.
Save z5h/504f4cce5672f918901e to your computer and use it in GitHub Desktop.
Get the result of updating a Javascript object while treating it as immutable.
/**
* Get the result of updating `obj` with `props`, while treating `obj`
* as immutable.
*/
var update = function(obj, props){
var keys = Object.keys(props),
key,
changed = false,
i;
//if props makes no changes, just return obj
for (i = 0; i<keys.length; i++){
key = keys[i];
if (props[keys] !== obj[keys] || !(key in obj)){
changed = true;
break;
}
}
if (!changed){
return obj;
}
//we can't set constructor. so traverse the prototype chain until
//we
// a) find something with a constructor, or,
// b) hit null
var root = obj;
var hasOwnProperty = Object.prototype.hasOwnProperty;
while(root !== null && !hasOwnProperty.call(root, 'constructor')) {
root = Object.getPrototypeOf(root);
}
//our return object will have root as it's prototype
var result = Object.create(root);
//if something in obj's prototype chain has overridden root,
//then apply that change to the return object
for (key in obj){
if (root === null || !(key in root && root[key] === obj[key])){
result[key] = obj[key];
}
}
//finally, copy everything from props into the result
for (i=0; i<keys.length; i++){
key = keys[i];
result[key] = props[key];
}
return result;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment