JavaScript Object Mirroring/One-way Property Synci

2019-03-04 00:41发布

问题:

For security purposes, I have a need for a "mirrored" object. i.e. if I create object A, and shallow-clone a copy of A and call it B, whenever a property of A changes, I hope to have B automatically update itself to reflect the changes, but not the other way around. In other words, one-way property syncing.

My question: is there already a solution out in the wild that I'm not aware of?

Was thinking of implementing a library with observe-js (https://github.com/polymer/observe-js), but thought I should ask around before proceeding. Thanks.

回答1:

Assuming you don't need to support IE8 and earlier, you can use getters to do that on modern browsers.

function proxy(src) {
  var p = {};
  Object.keys(src).forEach(function(key) {
    Object.defineProperty(p, key, {
      get: function() {
        return src[key];
      }
    });
  });
  return p;
}

var a = {
  foo: "Original foo",
  bar: "Original bar"
};
var b = proxy(a);

console.log(b.foo);    // "Original foo"
a.foo = "Updated foo"; // Note we're writing to a, not b
console.log(b.foo);    // "Updated foo"


回答2:

You can setup the prototype chain for this:

var a = {};
var Syncer = function(){};
Syncer.prototype = a;
var b = new Syncer();

a.foo = 123;
b.foo; // 123

b.bar = 456;
a.bar // undefined

Any property not set on b directly will be looked for on the prototype object, which is a.

You can even wrap this up in a convenience function:

var follow = function(source) {
  var Follower = function(){};
  Follower.prototype = source;
  return new Follower();
}

var a = {};
var b = follow(a);

a.foo = 123;
b.bar = 456;

a.foo; // 123
b.foo; // 123

a.bar; // undefined
b.bar; // 456