8

Javascript 的新代理功能为调试提供了一些有趣的功能。例如,您可以通过将对象放在代理后面来“保护”一个对象,get如果您访问未定义的属性,则该处理程序会抛出该处理程序。这有助于发现拼写错误和其他类型的错误。

这可以像这样使用:

class Something {
    constructor()
    {
        this.foo = "bar";

        allObjects.push(this);
    }
};

function defend(o)
{
    return new Proxy(o, DebugCheckHandler);
};

let rawSomething = new Something();
let defendedSomething = defend(rawSomething);

可以认真编写代码以仅处理defendedSomething. 然而在这个例子中,Something构造函数传递this到其他地方(到allObjects)。这最终rawSomethingdefendedSomething在代码库中同时使用两者具有相同的效果。

然后,代理引用不等于其原始引用这一事实会出现问题,因为rawSomething !== defendedSomething. 例如,allObjects.includes(defendedSomething)如果包含 ,将返回 false rawSomething,因为includes会进行严格===检查。

有没有一种很好的方法来解决这个问题而无需对代码进行太多更改?

4

2 回答 2

0

new可以:

  1. 创建一个继承自prototype构造函数的对象。
  2. 将其用作代理的处理程序。
  3. 调用将代理作为this值传递的构造函数。
function Something() {
  this.foo = "bar";
  allObjects.push(this);
}
function defendIntanceOf(C) {
  var p = new Proxy(Object.create(C.prototype), DebugCheckHandler);
  C.call(p);
  return p;
};
let defendedSomething = defendIntanceOf(Something);

注意我使用函数语法而不是类一,以便能够使用自定义值Function.call调用 [[Call]] 。this

于 2015-12-21T15:07:24.540 回答
0

Iirc,影响构造函数中的值的唯一方法this- 这是您在这里需要的 - 是通过子类化。我相信(但无法测试)以下内容应该有效:

function Defended() {
    return new Proxy(this, DebugCheckHandler);
//                   ^^^^ will become the subclass instance
}

class Something extends Defended {
//              ^^^^^^^^^^^^^^^^ these…
    constructor() {
        super();
//      ^^^^^^^ …should be the only changes necessary
//      and `this` is now a Proxy exotic object
        this.foo = "bar";

        allObjects.push(this);
    }
};

let defendedSomething = new Something();
于 2015-12-22T14:40:08.020 回答