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