如何为动态属性编写装饰器?

时间:2014-10-04 09:05:48

标签: javascript properties decorator

我写了一个answer,我必须写一些装饰器,所以我可以挂钩一些函数调用。但是,我也想挂钩属性设置器调用,但我不确定如何做到这一点。

在答案中,我想挂钩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)函数可以挂钩,我可以装饰它。但据我所知,这并不存在。

1 个答案:

答案 0 :(得分:0)

  

如何为动态属性编写装饰器?它有可能吗?

从ES5开始,使用真正的JavaScript对象,您可以通过{{1}将getter / setter对替换为属性来装饰您可以找到名称的属性,但不能找到您不知道名称的属性。 }}。在ES6中,可以创建“代理”,允许您在现有对象前面完全放置一个外观,甚至在您还不知道的名称上截取get / set,前提是您允许替换具有立面的物体。

在ES5的情况下,有问题的对象必须是一个真正的JavaScript对象,并且不能保证主机提供的对象如Object.defineProperty。在ES6的情况下,您必须能够使用自己的外观对象覆盖localStorage,但由于localStorage是主机提供的,所以无法保证您有充分的理由相信您不会被允许(并且已经在Chrome上试过,你不能在Chrome上)。