注意JavaScript对象属性更改的优雅方式

时间:2013-03-08 17:50:27

标签: javascript design-patterns

我正在开发一个带有服务器端组件的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,一切都很好。但这感觉真的很尴尬,我不想每次都要考虑同步,我设置了一个属性。所以在我看来,解决方案并不真正可用。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

一个set功能怎么样?

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

您可以将其与EventEmitter implementation结合使用,以便更轻松地观察更改。

答案 1 :(得分:1)

这正是__defineSetter()__旨在支持的内容。查看John Ressig的JavaScript Getters and Setters博客文章,了解一些很好的例子。从setter中发起事件非常简单。

答案 2 :(得分:0)

您可能需要考虑MeteorJS framework如果车轮改造不是您的行李。