2017-10-10 76 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