JavaScript对象镜像/单向属性同步

JavaScript对象镜像/单向属性同步,javascript,object.observe,Javascript,Object.observe,出于安全目的,我需要一个“镜像”对象。i、 e.如果我创建对象A,并浅克隆A的一个副本并将其命名为B,每当A的属性发生更改时,我希望B自动更新自身以反映更改,但不是相反。换句话说,单向属性同步 我的问题是:在野外已经有我不知道的解决方案了吗 我正在考虑用observejs()实现一个库,但我认为在继续之前应该先询问一下。谢谢。假设您不需要支持IE8及更早版本,您可以在现代浏览器上使用getter来实现这一点 function proxy(src) { var p = {}; Object

出于安全目的,我需要一个“镜像”对象。i、 e.如果我创建对象A,并浅克隆A的一个副本并将其命名为B,每当A的属性发生更改时,我希望B自动更新自身以反映更改,但不是相反。换句话说,单向属性同步

我的问题是:在野外已经有我不知道的解决方案了吗


我正在考虑用observejs()实现一个库,但我认为在继续之前应该先询问一下。谢谢。

假设您不需要支持IE8及更早版本,您可以在现代浏览器上使用getter来实现这一点

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"

您可以为此设置原型链:

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

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

b.bar = 456;
a.bar // undefined
任何未直接在
b
上设置的属性都将在原型对象上查找,即
a

您甚至可以将其封装在一个方便的函数中:

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

您需要支持哪些目标环境?特别是,您是否需要支持IE8及更早版本?不知何故,这似乎可以通过巧妙地使用“原型”属性来实现,但我不确定如何实现。@Katana314:问题是,当您稍后向B请求时,向B写入会隐藏A的值。我认为这不是OP想要的,但是OP似乎已经请求并运行了,所以…@settinghead:在IE8和更早的版本中基本上不能这样做,因为如果我理解所需的行为,你需要
Object.defineProperty
,IE8没有正确支持它。(你希望对
b
的写入被完全忽略,对吗?因此,如果
b
a
的前端,
b.foo=“无论什么”
都不应该改变你从
b.foo
得到的结果,对吗?)显然,如果你愿意要求每个人都调用a”,那么问题就会变得简单得多每个属性的函数。既然您支持旧浏览器,我认为您不必为没有使用简洁、现代的语法而抱怨太多。看起来这个解决方案不会将对象
b
a
同步。例如,在浏览器控制台中执行代码后,当我执行
a.foo=“Updated foo”
时,
b.foo
“Original foo”
@settinghead:对我有效:(堆栈片段目前似乎不起作用…)使用此解决方案,如果
a
获得新属性,它不会出现在
b
,对吗?@AlexWayne:对。如果这是一个要求,我们应该以某种方式将这两种方法结合起来(嗯,不确定具体如何)。或者等待ES6的代理,这正是针对这种情况的。但是,如果您将
foo
设置为
b
,然后请求
b.foo
,您将得到
b
的版本,而不是
a
。(你还忘了创建
b
)正确,这是“单向”的,不是吗?这不是我如何理解问题,但这并不意味着这不是OP想要的……不确定谁投了反对票。这将是一个很好且简单的解决方案,但我确实需要更新
b
,无论其属性是否已被重写。因此,您的意思是,如果您设置
b.foo
,然后设置
a.foo
b.foo
应该包含新值?因为是的,那要复杂得多。