为原型方法创建代理

亚历山大·米尔斯

我正在寻找一种避免为每个新对象实例创建新代理的方法。我有1个原型,我只想使用1个代理。这就是目标。如果我每个实例都使用一个代理,那么我可能会有成千上万个代理对象,这会严重影响性能。

最终,我正在做的是在原型方法上设置属性,如下所示:

const v = {
  foo: function () {
    assert.notEqual(this, v);
  }
};

v.foo.bar = function(){
   // I need `this` to be a certain value here
};

v.foo.zam = function(){
   // I need `this` to be a certain value here
};

但是我需要这些属性仍然具有与this原型方法本身相同的上下文(值)。

const assert = require('assert');

const v = {
  foo: function () {
    assert.notEqual(this, v);
  }
};

new Proxy(v.foo, {
  get: function(target, prop){
     console.log(this); // I am looking to get access to `x` here
  }
});


const x = Object.create(v);

x.foo();
const z = x.foo.bar; // I would have guessed this would have fired the Proxy `get` method.

我正在尝试做一些不可思议的事情,在这里我可以this从Proxy访问v原型方法值。在这种情况下,这意味着x要从代理访问值这有可能吗?另外,我想不通为什么当我读了代理的GET方法不叫bar物业x.foo,如x.foo.bar

我刚刚创建的这个Github要点更加接近:https : //gist.github.com/ORESoftware/757dd6285d554f4f52ae415fd39141a5

但是,我仍然认为不可能做我想做的事。这样做的理由是,我可以在原型中重用相同的Proxy对象,而不必为每个实例创建一个新的Proxy。

亚历山大·米尔斯

这里有一些不可思议的魔术,但它确实有效,您可以使用Object.defineProperty getter来设置代理原型方法的上下文(请注意,该方法仅适用于代码的同步部分)。

const proto = {};  // the prototype object 

const ctx = {
   val: null
};

const foo = function () {
    // the prototype method
    // do something with ctx.val which gets set dynamically
};

foo.bar = function(){
  // doing important stuff here
  // do something with ctx.val which gets set dynamically
};

const p = new Proxy(foo, {
  get: function (target, prop) {

    if (typeof prop === 'symbol') {
      return Reflect.get.apply(Reflect, arguments);
    }

    // do something with ctx.val
    // => ctx.val

  }
});


Object.defineProperty(proto, 'foo', {
  get: function() {
    ctx.val = this;  // set the context here!!
    return p;
  }
});

现在我们可以像这样使用它:

proto.foo.bar()

当访问foo时,它将为bar()动态设置ctx

我最终像这样使用它:

const o = Object.create(proto);
o.foo.bar();

o.foo()如果需要,我们也可以致电

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章