如何获取JavaScript代理的目标?
如何在此处访问如何获取JavaScript代理的目标?,javascript,ecmascript-6,proxy,Javascript,Ecmascript 6,Proxy,如何在此处访问myProxy的target(即myArray) 我试过很多方法。谷歌搜索了许多博客帖子,但没有找到获取目标的方法:(您可以使用以下方法复制代理返回的数据: 这将适用于代理/目标上的所有现有对象。因为代理包含您也可以执行的对象 const target_copy = Object.assign({}, my_proxy); 然后就可以很容易地检索诸如Object.keys(my_proxy).length之类的内容,如果目标是对象,则可以 您必须在target中创建一个函数来检索
myProxy
的target
(即myArray
)
我试过很多方法。谷歌搜索了许多博客帖子,但没有找到获取目标的方法:(您可以使用以下方法复制代理返回的数据:
这将适用于代理/目标上的所有现有对象。因为代理包含您也可以执行的对象
const target_copy = Object.assign({}, my_proxy);
然后就可以很容易地检索诸如
Object.keys(my_proxy).length之类的内容,如果目标是对象,则可以
您必须在target中创建一个函数来检索它,仅此而已
例如:
Object.keys( my_proxy )
然后当你打电话时:
class AnyClass {
constructor() {
this.target = this;
return new Proxy(this, this);
}
get(obj, prop) {
if (prop in obj)
return this[prop];
// your stuff here
}
getTarget() {
return this.target;
}
}
将按预期返回目标:)有一种聪明的方法可以做到这一点-您可以向代理添加一个get陷阱,并让它有条件地返回目标。就这样
let sample = new AnyClass;
console.log(sample.getTarget());
请记住,添加到陷阱中的代码行越多,对象的性能就越慢。希望这有帮助。添加以下get陷阱如何:
let resolveMode = false; // Switch that controls if getter returns target or prop.
function resolve(obj) {
resolveMode = true; // Turn on our switch
let target = obj.anything; // This gets the target not the prop!
resolveMode = false; // Turn off the switch for the getter to behave normally
return target; // Return what we got!
}
function createProxy() {
const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, {
get: function(target, prop) {
if (resolveMode) return target; // This is where the magic happens!
else return target[prop]; // This is normal behavior..
}
});
}
const myProxy = createProxy();
let target = resolve(myProxy);
您可以通过myProxy.myTarget
获取代理的目标:
const handler = {
get: (target, property, receiver) => {
if (property === 'myTarget') {
return target
}
return target[property]
}
}
const myArray = [Math.random(), Math.random()];
function createProxy() {
// const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, handler);
}
const myProxy = createProxy();
就像其他答案已经说过的那样,代理获取陷阱可以是一个优雅的解决方案
console.log(myProxy.myTarget) // [0.22089416118932403, 0.08429264462405173]
console.log(myArray === myProxy.myTarget) // true
此代码示例应该非常健壮,因为它:
- 通过使用
符号避免属性名称冲突
- 通过使用
Reflect.get
而不是target[property]
- 警告:小心原型继承-如果您的代理最终被用作原型,
not_self_a_proxy[IDENTITY]
调用将不会返回not_self_a_proxy
,而是返回原型的“IDENTITY”李>
其他答案给出了一些很好的解决方案。这里是@Yuci对类的回答,在这种情况下,只需定义一个特殊名称的实例变量即可。Proxy get函数返回它,底层目标也返回它
const IDENTITY = Symbol('proxy_target_identity')
const handler = {
get: (target, property, receiver) => {
if (property === IDENTITY) {
return target
}
return Reflect.get(target, property, receiver)
}
}
function createProxy() {
const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, handler);
}
const myProxy = createProxy();
const orignal_target = myProxy[IDENTITY]
我发现(在有时涉及代理对象的情况下,使用Vue.js,例如在观看组件道具时),无论是对象还是数组,我都可以使用JSON.stringify
:
class Foo {
constructor() {
this.__target__ = this;
return new Proxy(this, {
get: function (target, name) {
if (name in target) return target[name];
// your code here
}
});
}
}
let foo = new Foo();
let target = foo.__target__;
console.log('proxied Foo', foo);
console.log('recovered target', target, target.__target__.__target__);
这种方法也适用于数组目标,而Object.assign({},myProxy)
仅当目标是对象时才有效
但我对JavaScript代理非常陌生,我的知识有限。我可能不理解这种方法的局限性和注意事项。尽管如此,也许它能帮助一些人 你不能。这就是为什么它是一个代理。你想做什么,你为什么需要这个?@Bergi因为如果我有一个带有循环引用的对象,而这些循环引用在代理中,就没有办法安全地字符串化我的对象。我将获取超出堆栈大小的错误:(你能举个例子吗?循环引用(我想你指的是那些,不是依赖性)代理应该可以正常工作,因为myProxy===myProxy
仍然有效。不需要任何东西来控制目标。我的示例场景要求处理从web API调用返回的作为承诺拒绝的代理。完整行如下所示:var m=Object.assign({},拒绝)[0].message;
。谢谢Rashad!谢谢。这是我所需要的。我需要Vue创建的代理的目标,以便我可以将其作为获取请求的一部分传递。
class Foo {
constructor() {
this.__target__ = this;
return new Proxy(this, {
get: function (target, name) {
if (name in target) return target[name];
// your code here
}
});
}
}
let foo = new Foo();
let target = foo.__target__;
console.log('proxied Foo', foo);
console.log('recovered target', target, target.__target__.__target__);
let myTarget = JSON.parse(JSON.stringify(myProxy))