【问题标题】:Substitute Proxy exception替代代理例外
【发布时间】:2017-10-10 22:00:16
【问题描述】:

Proxy 捕获一个分配并且不确认它时,在严格模式的情况下TypeError 被抛出。但我会误用代理,需要ReferenceError

如何在第二次通话中获得ReferenceError

var code = `
  try {
    a = 1;
    console.log("Ok");
  } catch (e) {
    console.log(e.name);
  }
`;

var p = new Proxy({a:undefined}, {set(){}});

with (p) (function () {               eval(code); })(); // Ok
with (p) (function () { 'use strict'; eval(code); })(); // TypeError
         (function () { 'use strict'; eval(code); })(); // ReferenceError

PS:Same question in Russian.

【问题讨论】:

  • throw new ReferenceError(…) 工作吗?
  • “不确认”是什么意思?
  • @Ryan,在什么地方?只有当调用者处于严格模式时我才需要一个错误,否则什么都不会发生。并且code 不应更改。
  • @Bergi, {set(){}} - 如果在严格模式下(仅)从代码中调用 setter,则会导致错误,并且通过确认我的意思是 {set(){return true}} - 分配被认为是成功的并且不会发生错误。跨度>
  • @Qwertiy:检测调用者是否处于严格模式似乎是不可能的。这个是干什么的?一个噱头图书馆?

标签: javascript ecmascript-6 es6-proxy


【解决方案1】:

严格模式ReferenceError 仅在没有此类变量a 时发生。在with ({a: …}) a = …; 中,总是有一个。仅拦截分配的对象周围的代理对此没有任何改变。

您唯一能做的就是从您的对象中删除a 属性,或者让您的代理表现得好像它没有这样的属性:new Proxy({a: …}, {has(){ return false; }})。这两者都会在严格模式下导致ReferenceError。但是,这也意味着在草率模式下,它们将导致创建全局变量,这可能是不希望的。

严格模式 TypeError 仅在变量被视为不可变时发生,例如const 或者,对于 with 语句,不可写属性 - 带有 writable: false 的数据属性,没有设置器的附属属性,或任何其他对象,如 [[Set]] 返回 false 的代理.为避免这种情况,请使用 set 陷阱中的 return true 或使用在目标对象上分配属性的默认陷阱。

这两个异常是唯一依赖于严格模式的异常,您不能拦截它们,只能通过代理的其他行为引导它们。当然,你也可以只从你的陷阱中抛出异常,但这些不依赖于严格模式。

【讨论】:

  • 我对作用域隔离很感兴趣,所以删除代理(或其中的键)不是我想要的。
  • @Qwertiy 我看不出有什么问题,只是总是为此而抛出对全局变量的每次访问。如果你想隔离作用域,代码是否在严格模式下运行并不重要——分配给未声明的变量总是错误的。
  • 读取未赋值的变量总是错误的。但它的赋值只是严格模式下的错误。
猜你喜欢
  • 2013-09-06
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
  • 2016-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多