2015-11-04 60 views
0

我有很多小对象都需要完成非常类似的任务,我想用修饰器来修改这些对象,因为这样做对我来说更容易。问题是,一旦访问这些对象的某些数据时,我也需要触发内容,同时防止外部访问实际数据。因此,我正在使用闭包来存储私人数据并为外部访问提供神奇的增效器。最后,我也没有具体的原因使用构造函数。创建能够访问闭包的装饰器

这是对象和一个非常简化版本,让我头疼的部分:

var Foo = function() { 
    var hiddenState; 
    return { 
    set state (s) { 
     // Do something that justifies using magical accessors 
     state = s; 
    }, 
    get state() { 
     // Do something that justifies using magical accessors 
     return state; 
    } 
    } 
}; 

var o = new Foo(); 
o.state = 10; 

好了,现在是应该表现与其余不同,当使用它们的变异符某些对象。所以,我想,我只是覆盖mutators,就是这样:

// Let's suppose I have some reason to modify the magical accessors for some objects but not for others 
Object.defineProperty(o, 'state', { 
    get: function() {return hiddenState /*...*/}, 
    set: function (s) {state = s /*...*/} 
}); 

o.state; // Ouch! 

这是行不通的。我得到一个参考错误,因为我试图访问hiddenState,因为它没有在新的getter/setter对的范围内定义。

我怀疑JS转储只有当我通过新的mutators才能访问的闭包。有什么办法可以解决这个问题吗?

回答

1

您可以使用Object.getOwnPropertyDescriptor访问可访问hiddenState的封闭。另外,如果你不需要修改getter,就根本不覆盖它,它会持续下去。

var oldSetter = Object.getOwnPropertyDescriptor(o, 'state').set; 
Object.defineProperty(o, 'state', { 
    set: function (s) { 
    /* do something to s */ 
    oldSetter(s); 
    } 
}); 
+0

哇!这正是我期待的!我已经在考虑使用定制功能来保留旧的setter,但这样好多了。 –