1

I'm writing a compiler in JavaScript, and for the optimizer I'm following the usual pattern where a list of optimizations is run repeatedly until nothing happens. The obvious way to detect the 'nothing happens' condition is to have each optimization set a flag if it successfully does something. I'm wondering if there's a more elegant way to go about it.

In the abstract, the problem can be phrased like this: given a complex object (with many levels of subobjects including arrays with circular references etc.), run it through a possible transformation then detect whether anything has changed. So the question is whether there is a simple way to detect changes in a complex object.

Watch.js provides ways to detect changes in an object, but only at top level, and will trigger if a field is changed even if it is subsequently returned to its original value.

Another approach would be to make a deep copy of the object and then deep compare with the original. However, from other questions here, deep copy looks like a nontrivial operation and deep compare has challenges of its own.

Is there an elegant trick I'm missing, or should I just stick to letting each optimization pass do its own bit of bookkeeping?

icedwater
  • 4,701
  • 3
  • 35
  • 50
rwallace
  • 31,405
  • 40
  • 123
  • 242
  • 1
    Backbone.js has this built-in. http://backbonejs.org/#Model-changedAttributes – Diodeus - James MacFarlane Jan 03 '14 at 18:34
  • @Diodeus Interesting! I get the impression from the documentation that it only sees top-level attribute changes, though, not changes in subobjects? – rwallace Jan 03 '14 at 18:40
  • Just brainstorming: Whatever you use to detect changes on the top level, couldn't you simply apply that to every array and subobject inside your original object? – basilikum Jan 03 '14 at 19:01
  • Have you looked at [Object.observe](http://updates.html5rocks.com/2012/11/Respond-to-change-with-Object-observe)? It's behind a flag now though. – Dan Abramov Jan 03 '14 at 20:25

1 Answers1

1

I would just post this as a comment, but I don't have the required rep.

I don't know if this would work in your situation, but what you could do is convert to JSON, then compare the strings:

JSON.stringify(firstObject) === JSON.stringify(secondObject) 

Was looking around a bit more, and found another stackoverflow post with a similar question. There is a solution similar to mine, but what I found most interesting was the second solution, not chosen as the answer, I think it has what you need: Object comparison in JavaScript

Community
  • 1
  • 1
Nathan
  • 409
  • 4
  • 15