2014-10-04 31 views
0

我写了一个answer,我不得不写一些装饰器,这样我就可以挂钩一些函数调用。但是,我也想要挂钩属性setter调用,但我不知道如何做到这一点。如何为动态属性编写装饰器?

在答案中,我想钩入localStorage,以便我可以听取任何更改。我通过装饰setItem()removeItem()函数来完成此操作。

我知道我可以通过创建新的,在某些时候调用原件来装饰功能。

var _setItem = localStorage.setItem; 
localStorage.setItem = function() { 
    _setItem.apply(this, arguments); 
    localStorageObserver.notifySubscribers(arguments[0]); 
}; 

这工作的很好,但还有其他用途,我希望挂钩,财产访问。以下是所有等价物的存储对象:

localStorage.setItem('someProperty', 'value'); 
localStorage.someProperty = 'value'; 
localStorage['someProperty'] = 'value'; 

所以我需要挂接到最后两种情况,但我不知道如何可以完成。

如何为动态属性编写装饰器?这是否可能?

我想我可以手动创建属性,因为它们被设置为隐藏存储对象完成的工作,但这看起来不是很有伸缩性。如果有一个简单的setProperty(name, value)函数可以插入,我可以修饰它。但据我所知,这并不存在。

+0

'localStorage.key'说这是一个函数 – loveNoHate 2014-10-04 09:10:48

+1

对不起,不好的例子。 – 2014-10-04 09:12:29

+0

;)............. – loveNoHate 2014-10-04 09:14:58

回答

0

如何为动态属性编写装饰器?这是否可能?

由于ES5的,与真正的JavaScript对象,你可以装饰的属性,你可以找到的名字,而不是那些你还不知道的名字,用一个getter/setter方法对通过更换物业Object.defineProperty。在ES6中,可以创建“代理”,允许您在现有对象的前面完全放置外观,即使您的名称尚不知道的proeprties也会拦截get/set,前提是您允许替换与门面的对象。

在ES5的情况下,所讨论的对象必须是一个真正的JavaScript对象,并且不能保证主机提供的对象如localStorage。在ES6的情况下,您必须能够用自己的外观对象覆盖localStorage,但由于localStorage是由主机提供的,因此无法保证您有足够的理由相信您不会被允许(并尝试过)在Chrome上,你不能在Chrome上)。

+0

我可以忍受这一点。至少在一个门面对象的情况下,我可以说,如果你想充分利用正在添加的功能,你必须使用门面。我认为在这种情况下这是合理的。 – 2014-10-10 20:35:23