我正在使用一个库将东西转换为ES6代理对象,另一个库因为我传递了其中一个(我的代码很糟糕,我知道)而出现了问题,我无法弄清楚如何取消代理对象的代理。但是我只是太蠢了。代理可以做任何事!
我找到了一个技巧。在我的情况下,我无法控制代理的创建(mobx可观察值)。所以解决方案是:
JSON.parse(JSON.stringify(your.object))
尝试使用JSON.parse(JSON.stringify(proxyObj))
但这会删除任何无法字符串化的内容(例如类、函数、回调等...),这对我的用例不好,因为我在对象中有一些回调函数声明,并且我希望将它们视为对象的一部分。然而,我发现使用Lodash cloneDeep函数可以很好地将代理对象转换为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.stringify(...))
get
处理程序需要一个 else
分支,在非 target
属性上正常运行(即使用 Reflect.get
)。 - Bergi如果您不想使用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
Proxy
转换为普通的 Object
的方法是将其值assign
给一个新的对象: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));
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);
import { observable, toJS } from "mobx";
const observed = observable({ foo: 'bar' })
const obj = toJS(observed)
this.self=this
。self
属性,这样就可以了。 proxiedMyObj.self===myObj //返回true
。