如何获取JavaScript代理的目标?

时间:2018-06-29 07:33:24

标签: javascript ecmascript-6 proxy

function createProxy() {
    const myArray = [Math.random(), Math.random()];
    return new Proxy(myArray, {});
}

const myProxy = createProxy();

如何在此处访问target的{​​{1}}(即myArray)?

我尝试了很多方法。在Google上搜索了许多博客文章,但没有找到目标的方法:(

8 个答案:

答案 0 :(得分:3)

有一个聪明的方法-您可以向代理添加 get 陷阱,并使其返回 target > 。就是这样。

File file = new File("/sdcard/Documents/asd.txt");

请记住,添加到陷阱的代码行越多,对象的性能就越慢。希望这会有所帮助。

答案 1 :(得分:1)

您可以使用Object.assign()复制代理返回的数据:

const target_copy = Object.assign({}, my_proxy);

这将适用于代理服务器/目标服务器上所有现有的enumerable own properties

答案 2 :(得分:1)

如果目标是对象,则可以。

仅此而已,您必须在target中创建一个函数来检索它。

示例:

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;
   }
}

然后致电:

let sample = new AnyClass;
console.log(sample.getTarget());

将按预期返回目标:)

答案 3 :(得分:1)

如何添加以下获取陷阱:

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();

您可以通过myProxy.myTarget获取代理的目标:

console.log(myProxy.myTarget) // [0.22089416118932403, 0.08429264462405173]
console.log(myArray === myProxy.myTarget) // true

答案 4 :(得分:1)

其他答案给出了一些好的解决方案。这是@Yuci针对类的答案,在这种情况下,就像定义一个特殊名称的实例变量一样简单。 Proxy get函数返回它,基础目标也返回它。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath) as! ProductTableViewCell

    // Configure the cell...
    let productLine = productLines[indexPath.section]
    let products = productLine.products
    let product = products[indexPath.row]

    cell.product = product

    return cell
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    let productLine = productLines[section]

    return productLine.name
}

// Mark: UITableViewDelegate

var selectedProduct: Product?

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    let productLine = productLines[indexPath.section]
    let product = productLine.products[indexPath.row]
    selectedProduct = product
    performSegue(withIdentifier: "ShowProductDetail", sender: nil)


}

// Mark: - Navigation

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
    if segue.identifier == "ShowProductDetail" {
        let DetailVC = segue.destination as! DetailViewController
        DetailVC.product = selectedProduct

    }
}

答案 5 :(得分:0)

由于代理包含一个对象,您也可以这样做

Object.keys( my_proxy )

然后变得很容易检索诸如Object.keys( my_proxy ).length

之类的东西

答案 6 :(得分:0)

就像其他答案已经说过的那样,代理获取陷阱可以是一个很好的解决方案。

const IDENTITY = Symbol('proxy_target_identity')
const handler = {
  get: (target, property, receiver) => {
    if (property === IDENTITY && target.hasOwnProperty(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]

此代码示例应该非常健壮:

  • 通过使用Symbol
  • 避免属性名称冲突
  • 使用Reflect.get而不是target[property]来覆盖所有获取方案
  • 与原型继承一​​起使用-万一您的代理最终被用作原型,即使从未真正被代理,继承者也不会返回自己。

答案 7 :(得分:0)

我发现(使用Vue.js有时涉及代理对象,例如在观看组件道具时),我可以使用JSON.stringify既可以获取目标,也可以获取目标,无论它是对象还是数组: / p>

let myTarget = JSON.parse(JSON.stringify(myProxy))

此方法也适用于Array目标,而Object.assign({}, myProxy)仅在目标是Object时有效。

但是我对JavaScript代理非常陌生,我的知识有限。我可能不了解这种方法的局限性和注意事项。不过,也许它可以帮助某人!