如何将ES6代理重新转换为普通对象(POJO)



我使用的是一个将事物转换为ES6代理对象的库,而另一个库我认为很难接受,因为我正在传递其中一个(我知道我的代码是一个闹剧(,我不知道如何取消代理对象。

但我只是在装聋作哑。代理人可以做任何事情!

我发现了一个黑客。在我的情况下,我无法控制代理的创建(mobx可观察值(。因此,解决方案是:

JSON.parse(JSON.stringify(your.object))

尝试使用JSON.parse(JSON.stringify(proxyObj)),但它删除了任何无法字符串化的内容(如类、函数、回调等(,这对我的用例不好,因为我的对象中有一些回调函数声明,我希望将它们视为对象的一部分。然而,我发现使用Lodash-cloneDeep函数可以很好地将Proxy对象转换为POJO,同时保持对象结构。

convertProxyObjectToPojo(proxyObj) {
return _.cloneDeep(proxyObj);
}

使用排列运算符怎么样?

const plainObject = { ...proxyObject };
pp = new Proxy(
{a:1},
{
get: function(target, prop, receiver) { 
if(prop==='target') return target 
}
}
)

但只有当您能够控制代理的创建时,这才会起作用。事实证明这更容易:

pojo = Object.assign({}, proxyObj) // won't unwrap nested proxies though

对于喜欢这个答案的读者来说,David Gilbertson的新答案可能会更好。我个人更喜欢lodash clonedeep。最流行的似乎是JSON.parse(JSON.stringfy(…((

如果你不想使用lodash object.assign({},val(方法是可以的。但如果val包含嵌套对象,它们将被代理。所以它必须像这样递归地完成:

function unproxify(val) {
if (val instanceof Array) return val.map(unproxify)
if (val instanceof Object) return Object.fromEntries(Object.entries(Object.assign({},val)).map(([k,v])=>[k,unproxify(v)]))
return val
}

事实上,这是一个深层次的克隆功能。我认为如果val包含Map对象,这是不起作用的,但您可以按照相同的逻辑修改函数。

如果您想取消对Vue3代理的装箱,Vue3提供了一个函数:toRaw

谢谢@sigfried的回答,这正是我想要的!

这里有一个稍微详细一点的版本,使用Symbol来避免与真实道具名称发生冲突。

const original = {foo: 'bar'};
const handler = {
get(target, prop) {
if (prop === Symbol.for('ORIGINAL')) return target;
return Reflect.get(target, prop);
}
};
const proxied = new Proxy(original, handler);
console.assert(original !== proxied);
const unproxied = proxied[Symbol.for('ORIGINAL')];
console.assert(original === unproxied);

通常您会使用mobx-util-toJS((。

import { observable, toJS } from "mobx";
const observed = observable({ foo: 'bar' })
const obj = toJS(observed)

假设您无法访问原始目标,将Proxy转换为assign的最快方法是将其值转换为新的普通Object:

const obj = Object.assign({}, proxy);

或者使用扩展器:

const obj = { ...proxy };

示例

const user = {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
};
const handler = {
get(target, property) {
return target[property];
}
};
const proxy = new Proxy(user, handler);
const a = Object.assign({}, proxy);
console.log(`Using Object.assign():`);
console.log(`Hello, ${a.firstName} ${a.lastName}!`);
console.log(JSON.stringify(a));
const s = { ...proxy };
console.log(`Using spreader:`);
console.log(`Hello, ${s.firstName} ${s.lastName}!`);
console.log(JSON.stringify(s));

在未装箱的对象构造函数中,添加this.self=this

然后确保您的get处理程序允许返回self属性,并且您已经设置好了。proxiedMyObj.self===myObj //returns true

最新更新