recursion - Most elegant way to save only primitive properties of a Javascript object -
i have object lots of own , inherited methods. need make simple snapshot of primitive properties.
what's elegant way how it?
javascript snippet
function copy(source) { var target; if (source) { target = {}; (var key in source) { var prop = source[key], type = typeof prop; if (type === "string" || type === "number" || type === "boolean") { target[key] = prop; } if (type == "object") { target[key] = copy(prop); } } } return target; }
with underscore.js
function copy(source) { var target; if (source) { target = {}; _.filter( _.keys(source), function( key ) { var prop = source[key]; if (!_.isfunction(prop) && !_.isobject(prop)) { target[key] = prop; } if (_.isobject(prop)) { target[key] = copy(prop); } }); } return target; }
the problem here dealing mix of types may or may not want loose typing javascript offers. without walking given array impossible tell whether contains primitives , might therefore want keep or whether contains objects or functions want filter out.
i realise library recommendations oldest hat, i'm going recommend use underscore.js ( or derivative such lodash ) gives whole lot of super-convenient functions use whole time. in real sense these feel missing part of core javascript language - in fact in cases wrapping native functionality, allowing avoid platform inconsistencies.
if have underscore included in library can find non-object property names of given object this:
var myobject = { a: "hello", b: "goodbye", c: function() { console.log(this.b);} d: { hello: "banana" } }; _.filter( _.keys(myobject), function( key ) { return ! _.isobject(myobject[key]); }) // => ["a", "b"]
this tidied function clone object, of course it's unnecessary because underscore offers _.pick
, returns copy of object whitelisted properties:
_.pick( myobject, _.filter( _.keys(myobject), function( key ) { return ! _.isobject(myobject[key]);}))
by flipping !_.isobject
can retrieve properties objects, , perform similar mapping on if necessary. wrapping both in function can call recursively on child objects want clone.
this answers question, aware might not best way perform undo/redo actions, mention in comments use plan put to. may easier record actions , states onto history stack recording actual changes action performs, can retrieved , reverted safely without needing keep snapshots of data.
Comments
Post a Comment