Javascript object encapsulation that tracks changes

Is it possible to create an object container where you can track changes.

The specified object is a complex nested data object. (compatible with JSON).

A wrapper allows you to retrieve an object and save changes without specifying specifically what changes

Is there a design pattern for this kind of encapsulation

Deep cloning is not an option since I am trying to write a wrapper like this so as not to do this.

A serialization solution should only be considered if there are no other solutions.

An example of use might be

var foo = state.get(); // change state state.update(); // or state.save(); client.tell(state.recentChange()); 

Jsfiddle snippet can help: http://jsfiddle.net/Raynos/kzKEp/

It seems that implementing an internal hash to track changes is the best option.

[change]

To clarify this, the action is performed on node.js on the server. The only thing that changes is that the solution may be specific to the implementation of V8.

+4
source share
5 answers

Eliminating the aspect of this problem, there are only three ways to find out if something has changed:

  • Keep a copy or view for comparison.
  • Observe that change itself is happening along the way.
  • Notice of change.

Now return these concepts to javascript and you have the following templates:

  • Copy: either a deep clone, full serialization, or a hash.
  • Observe: force the use of the installer or click on the javascript mechanism (not very suitable)
  • Notify: change code that makes changes to publish events (again, not very suitable).

Seeing how you ruled out a deep clone and using setters, I think your only option is some form of serialization ... see hash here .

+2
source

You will have to wrap all your nested objects with a class that tells you when something changes. The fact is that if you place an observer only in a first-level object, you will receive notifications only for the properties contained in this object.

For example, imagine you have this object:

 var obj = new WrappedObject({ property1: { property1a: "foo", property1b: 20, } }) 

If you do not wrap the object contained in porperty1, you will receive the โ€œreceiveโ€ event only for property1 , and only this, because when someone starts obj.property1.property1a = "bar" , the only interaction you will have with obj will be when it requests a reference to the object contained in property1 , and the modification will occur in an unobservable object.

The best approach I can imagine is to repeat all the properties when wrapping the first object and creating a wrapper object recursively for each typeOf(property) == "Object" .

I hope my understanding of your question was correct. Sorry if not! This is my first answer here: $.

+2
source

There is something called reactive programming , similar to what you are asking for, but its more active participation and is likely to be superfluous.

It seems you would like to keep a history of values, right? This should not be too complicated if you restrict the changes to the setter function. Of course, this is more complicated in javascript than in some other languages. Real private fields require some clever use of closures.

Assuming you can do all this, just write something like this in the installer.

 function setVal(x) { history.push(value); value = x; } 
+1
source

You can use a solution that uses processing.js . Write a script that usually refers to a wrapped object ...

 var foo = state.get(); foo.bar = "baz"; state.update(); client.tell(state.recentChange()); 

... but in the browser (or on the server, if download speed is important) before starting, analyze the code and convert it to this,

 var foo = state.get(); state.set(foo, "bar", "baz"); state.update(); client.tell(state.recentChange()); 

This can also be used for other useful things, such as operator overloading:

 // Before conversion var a=new Vector(), b=new Vector(); return a + b * 3; // After conversion var a=new Vector(), b=new Vector(); return Vector.add(a,Vector.multiply(b,3)); 
+1
source

It appears that node-proxy implements a way to do this by wrapping a proxy server around the entire object. I will examine in detail how this works.

https://github.com/samshull/node-proxy

0
source

Source: https://habr.com/ru/post/1334600/


All Articles