我经常遇到这样的情况:在解构某些对象的属性之前,我想对它们调用相同的方法。例如,我将有一个记录,其中某些属性具有从信号/回调返回值的方法,而其他属性则具有仅返回普通值的相同方法。我想解构它们,这样我最终只得到这些值:
type ValueLike<T> = { value(): T };
const cb = () => 50;
const aProp: ValueLike<number> = { value: () => cb() };
const bProp: ValueLike<number> = { value: () => 100 };
const props = { a: aProp, b: bProp };
const { a, b } = props // Want to end up with { a: 50, b: 100 };
当然,我可以编写一些辅助函数,称为
unwrapAll()
之类的函数,它接受一个对象,在每个属性上调用 .value()
,将它们分配给一个新对象,然后对其进行解构。但是,我想知道是否有某种方法可以避免创建中间对象,而不必单独分配每个属性(即const a = props.a.value(), const b = props.b.value(), ...
)
最接近您所要求的事情可以通过代理对象来实现。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Proxy 对象使您能够为另一个对象创建代理, 它可以拦截并重新定义基本操作 对象。
特别是重新定义属性获取器
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get
handler.get()方法是[[Get]]对象内部的陷阱 方法,由属性访问器等操作使用。
function unwrapValues(target) {
//return a Proxy wrapping the passed target object
return new Proxy(target, {
//that redefines the property getter (for any property)
get: function(target, prop, receiver) {
var item = Reflect.get(target, prop, receiver);
//as something that will return the .value() result instead of its actual value
return item && typeof item.value === 'function' ? item.value() : undefined;
}
});
}
var aProp = { value: () => 50 };
var bProp = { value: () => 100 };
var props = { a: aProp, b: bProp };
var unwrappedProps = unwrapValues(props);
var { a, b } = unwrappedProps;
console.log(a, b);
//==> a is 50, b is 100