如何获取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))