我使用的是一个将事物转换为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