【问题标题】:Exceeding maximum stack call size using Proxies使用代理超过最大堆栈调用大小
【发布时间】:2018-06-08 22:56:03
【问题描述】:

我正在尝试为某个对象创建代理,以检查属性是否被访问或修改,然后console.log 被更改的属性。我对 JavaScript 还很陌生,所以我不确定是什么导致堆栈溢出。我认为这是由于console.log 的一个奇怪的范围问题,但我不确定。这就是我的处理程序的样子

var handler = {
    set: function(obj, prop, value) {
         console.log(prop);
         obj[prop] = value;
    }
    get: function(obj, prop, receiver) {
          if (typeof prop !== 'symbol') console.log(prop);
          return obj[receiver];
    }
};

我正在使用这一行将处理程序分配给名为 ctxCanvasRenderingContext2D 元素。

 watchedCtx = new Proxy(ctx, handler);

我在 get 属性方法中添加了额外的检查,因为我从 get 方法收到了很多 Symbol 原语,我认为这是问题所在,所以我尝试将它们过滤掉。有没有其他人遇到过这个问题或知道可能是什么原因造成的?

【问题讨论】:

    标签: javascript debugging ecmascript-6 stack proxies


    【解决方案1】:

    在您的情况下,拼写错误是obj[receiver],应该是obj[prop]receiver 是一个对象(通常是您的代理本身),因此通过执行obj[receiver],您将receiver 转换为字符串,这需要调用get,然后触发您所看到的无限递归。这将解决您的问题,但您现在可能想知道,那么 receiver 是什么?

    在这种情况下,receiver 对于代理的正确运行至关重要。如果您正在编写代理,最简单的处理方法是使用Reflect 中的方法来确保您实际上正确地保留了行为。

    var handler = {
      set: function(obj, prop, value, receiver) {
        console.log(prop);
    
        return Reflect.set(obj, prop, value, receiver);
      }
      get: function(obj, prop, receiver) {
        if (typeof prop !== 'symbol') console.log(prop);
    
        return Reflect.get(obj, prop, receiver);
      }
    };
    

    Reflect 方法执行代理执行的完全相同的原始行为,因此通过使用它们,您可以避免自己没有正确实现它们的危险。

    【讨论】:

    • 谢谢,解决了这个问题。现在我收到了TypeError: Illegal Invocation
    • 这将需要对您的代码进行更多更改。我建议阅读stackoverflow.com/questions/43927933/… 之类的内容,简而言之,您正在从CanvasRenderingContext2D 调用一个函数,但是将其传递给代理而不是真正的画布,这会导致错误,因此您必须@ 987654335@ 或包装函数,以便它们传递正确的上下文。
    猜你喜欢
    • 2020-01-05
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 2014-08-19
    • 1970-01-01
    • 2015-10-24
    • 2015-12-29
    相关资源
    最近更新 更多