跟踪变化的Javascript对象封装

发布于 2024-10-10 14:27:39 字数 592 浏览 2 评论 0原文

是否可以创建一个可以跟踪更改的对象容器

所述对象是一个复杂的嵌套数据对象。 (符合 JSON)。

包装器允许您获取对象并保存更改,而无需具体说明更改是什么

是否存在这种封装的设计模式

深度克隆不是一个选项,因为我正在尝试编写这样的包装器以避免就是这么做的。

只有在没有其他解决方案的情况下才应考虑序列化解决方案。

使用示例是

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

jsfiddle 片段可能会有所帮助: http://jsfiddle.net/Raynos/kzKEp/

似乎实现内部哈希来跟踪更改是最好的选择。

[编辑]

澄清一下,这实际上是在服务器上的 Node.js 上完成的。唯一改变的是该解决方案可以特定于 V8 实现。

Is it possible to create an object container where changes can be tracked

Said object is a complex nested object of data. (compliant with JSON).

The wrapper allows you to get the object, and save changes, without specifically stating what the changes are

Does there exist a design pattern for this kind of encapsulation

Deep cloning is not an option since I'm trying to write a wrapper like this to avoid doing just that.

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

An example of use would be

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

A jsfiddle snippet might help : http://jsfiddle.net/Raynos/kzKEp/

It seems like implementing an internal hash to keep track of changes is the best option.

[Edit]

To clarify this is actaully done on node.js on the server. The only thing that changes is that the solution can be specific to the V8 implementation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

迷途知返 2024-10-17 14:27:42

您可以使用 processing.js 使用的解决方案。
编写正常访问包装对象的脚本...

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

...但是在运行之前在浏览器中(或者在服务器上,如果加载速度很重要),解析代码并将其转换为此,

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

这也可以用于执行以下操作其他有用的东西,例如运算符重载:

// 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));

You can use the solution that processing.js uses.
Write the script that accesses the wrapped object normally...

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

...but in the browser (or on the server if loading speed is important) before it runs, parse the code and convert it to this,

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

This could also be used to do other useful things, like 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));
凹づ凸ル 2024-10-17 14:27:42

看起来node-proxy通过将代理包装在整个对象上来实现此目的。我将更详细地了解它是如何工作的。

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

It would appear that node-proxy implements a way of doing this by wrapping a proxy around the entire object. I'll look into more detail as to how it works.

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

只想待在家 2024-10-17 14:27:41

抛开这个问题的 javascript 方面,只有三种方法可以知道某些内容是否发生了变化:

  1. 保留副本或表示形式以进行比较。
  2. 观察传输过程中发生的变化本身。
  3. 收到变更通知。

现在将这些概念带回 JavaScript,您将得到以下模式:

  1. 复制:深度克隆、完整序列化或哈希。
  2. 观察:强制使用 setter,或者利用 javascript 引擎(不太适用)
  3. 通知:修改发布事件的代码(同样,不是很适用)。

鉴于您已经排除了深层克隆和设置器的使用,我认为您唯一的选择是某种形式的序列化......请参阅 哈希实现在这里

Stripping away the javascript aspect of this problem, there are only three ways to know if something has changed:

  1. Keep a copy or representation to compare with.
  2. Observe the change itself happening in-transit.
  3. Be notified of the change.

Now take these concepts back to javascript, and you have the following patterns:

  1. Copy: either a deep clone, full serialization, or a hash.
  2. Observe: force the use of a setter, or tap into the javascript engine (not very applicable)
  3. Notify: modifying the code that makes the changes to publish events (again, not very applicable).

Seeing as you've ruled out a deep clone and the use of setters, I think your only option is some form of serialisation... see a hash implementation here.

向日葵 2024-10-17 14:27:41

您必须使用一个类来包装所有嵌套对象,以便在发生更改时向您报告。问题是,如果您仅将观察者放置在第一级对象中,您将仅收到该对象中包含的属性的通知。

例如,假设您有这个对象:

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

如果您不包装 porperty1 中包含的对象,您将只会收到 property1 的“get”事件,仅此而已,因为当有人运行 < code>obj.property1.property1a = "bar" 您与 obj 的唯一交互是当它请求 property1 中包含的对象的引用时,并且修改将发生在未观察到的对象中。

我能想到的最好的方法是在包装第一个对象时迭代所有属性,并为每个 typeOf(property) == "Object" 递归地构造一个包装器对象。

我希望我对你的问题的理解是正确的。抱歉,如果没有!这是我在这里的第一个答案:$。

You'll have to wrap all your nested objects with a class that reports you when something changes. The thing is, if you put an observer only in the first level object, you'll only receive notifications 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 don't wrap the object contained in porperty1, you'll only receive a "get" event for property1, and just that, because when someone runs obj.property1.property1a = "bar" the only interaction that you'll have with obj, will be when it asks for the reference of the object contained in property1, and the modification will happen in an unobserved object.

The best approach I can imagine, is iterating over all the properties when you wrap the first object, and constructing recursively a wrapper object for every typeOf(property) == "Object".

I hope my understanding of your question was right. Sorry if not! It's my first answer here :$.

毁虫ゝ 2024-10-17 14:27:41

有一种叫做 反应式编程 的东西,类似于你所问的问题,但它更复杂,并且可能会太过分了。

看来您想保留价值观的历史,对吗?只要您限制对 setter 函数的更改,这应该不会太难。当然,这在 javascript 中比在其他一些语言中更困难。真正的私有领域需要巧妙地使用闭包。

假设您可以做到所有这些,只需将类似的内容写入设置器即可。

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

There's something called reactive programming that kind of resembles what you ask about, but its more involved and would probably be overkill.

It seems like you would like to keep a history of values, correct? This shouldn't be too hard as long as you restrit changes to a setter function. Of course, this is more difficult in javascript than it is in some other languages. Real private fields demand some clever use of closures.

Assuming you can do all of that, just write something like this into the setter.

function setVal(x)
{
    history.push(value);
    value = x;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文