2017-10-10 35 views
0

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.

+1

'抛出新的ReferenceError(...)'工作吗? – Ryan

+0

你是什么意思“不确认”? – Bergi

+0

@瑞恩,在什么地方?只有当调用者处于严格模式时,我才需要一个错误,否则什么都不应该发生。而'代码'不应该改变。 – Qwertiy

回答

0

严格模式ReferenceError只发生在没有这样的变量a。在with ({a: …}) a = …;,总是有一个。围绕仅拦截分配的对象的代理不会改变关于此的任何事情。

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

严格模式TypeError发生只有当变量被认为是不可变的,例如一个constwith声明,一个不可写属性 - 一个数据属性与writable: false,一个没有setter的附件属性,或者像[[Set]]返回false的代理上的任何其他对象。为避免此情况,请从set陷阱中输入return true或使用在目标对象上分配属性的默认陷阱。

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

+0

我对范围隔离很感兴趣,所以删除代理(或键入它)不是我想要的。 – Qwertiy

+0

@Qwertiy我没有看到任何错误,只是总是抛出每个访问的全局变量。如果你想要隔离范围,代码是否在严格模式下运行并不重要 - 分配给未声明的变量总是一个错误。 – Bergi

+0

读取未分配的变量始终是错误。但是在严格模式下分配它只是一个错误。 – Qwertiy