注意JavaScript对象属性变化的优雅方式

Elegant way to notice JavaScript object attribute changes

本文关键字:方式 变化 JavaScript 对象 属性 注意      更新时间:2023-09-26

我正在开发一个带有服务器端组件的JavaScript应用程序。其目的是在多个浏览器之间同步画布上的多个不同对象(即具有相同的外观)。同步由服务器端组件完成,该组件向所有浏览器广播单个更改。当一个对象发生变化时,它必须通知服务器,然后由服务器负责通知其他浏览器。

画布上的对象由JavaScript对象表示,这些对象的属性决定了用户的外观。当然,并非所有属性对外观都很重要。因此,只有重要属性的更改才需要传输到其他浏览器。有不同的"类"的对象,但所有的对象"继承"从一个共同的"超类"(我知道,类继承术语并不真正在JavaScript中工作,但在这种情况下,我认为这是更容易的方式)。

现在,我在以一种优雅的方式发送客户机-服务器通知方面遇到了一些麻烦。目前,我有针对不同对象的所有重要属性的setter方法。这些setter方法调用一个函数,该函数将通知发送到服务器。

我真的不喜欢这个解决方案,因为它引入了很多样板代码。理想情况下,当我创建一个新对象时,我希望能够只指定重要的属性并使用它。监视这些属性变化的逻辑可以在"超类"中。但我不知道如何实现这一点。也许有一种方法可以在运行时动态地构建setter ?或许还有其他我没有想到的方法?

如果有人能想到解决这个问题的办法,我很乐意听听。

提前感谢!

编辑:

我不得不撤销接受的答案(通过Object.defineProperty动态创建getter和setter),因为虽然我认为它会解决我的问题,但它并没有真正解决。现在,当一个属性通过触发setter的直接属性赋值被改变时,我就会得到通知,例如:

SynchronizedObject.importantProp = 'someValue';

但正如我注意到的,在许多情况下,importantProp是一些更复杂的对象。这些对象通常通过getter而不是setter来更新。

SynchronizedObject.importantProp.x = 'someValue';

据我所知,我没有机会注意到我的动态getter/setter实现以这种方式完成的更改。要使用它,我必须改变访问对象的方式。

prop = SynchronizedObject.importantProp;
prop.x = 'someValue';
SynchronizedObject.importantProp = prop;

这样,setter就被使用了,一切都很好。但这感觉很尴尬我不想每次设置属性时都考虑同步问题。因此,在我看来,这个解决方案并不是真正可用的。

有人能帮忙吗?

一个set函数怎么样?

MyObj.prototype.set = function(key, value) {
    this[key] = value;
    // do other things
};

您可以将其与EventEmitter实现结合起来,以便于观察更改。

这正是__defineSetter()__打算支持的。查看John Ressig的JavaScript getter和setter博客文章,了解一些很好的例子。从setter内部触发一个事件是非常简单的。

如果你不喜欢重新设计轮子,你可以考虑使用MeteorJS框架