2017-05-05 45 views
0

有沒有簡單的方法來斷言對象是代理的目標對象?ES2015代理服務器:斷言代理服務器與目標對象相同

const o = {}; 
const p = new Proxy(o, {}); 

平等運營商似乎並不工作,as outlined in this paper on page 6

o == p; // false 
o === p; // false 
const q = new Proxy(o, {}); 
p === q; // false 

有什麼辦法來驗證它們指向同一個對象,然後其他字符串化和重新分析對象?

典型的用例:

我想比較非與代理節點代理之一。由於我自己創建了代理,因此我知道應該預期哪些行爲。

const nodeList = new Proxy(document.querySelectorAll('div'), { 
    get(target, key) { return new Proxy(target[key], {}); } 
}); 

const specificNode = document.querySelector('div[data-target]'); 

for (const node of nodeList) { 
    if (node === specificNode) { doSomethingElse(); } // Never happens, even if specificNode is in the nodeList 
} 
+0

你爲什麼要在意?如果你不知道代理的作用,它可能表現得像「目標」或絕對不行。 – Bergi

+0

@Bergi請參閱上面的示例用例。 – nils

+0

爲什麼不寧願'if(「target」in node.dataset)... else'?當然,創建內部代理沒有任何陷阱是毫無意義的。 – Bergi

回答

1

當您自己創建代理時,還可以使其具有可比性。例如給一個方法來識別其目標:

const associatedTarget = Symbol(); 
const p = new Proxy(target[key], {}); 
p[associatedTarget] = target[key]; 
return p; 

… 
if (node[associatedTarget] === specificNode) 

一個更好的想法可能是給每個目標一個單獨的代理,這樣就可以得到代理的特定節點,並通過===比較一下:

const proxies = new WeakMap(); 
function makeUniqueProxy(t) { 
    if (!proxies.has(t)) 
    proxies.set(t, new Proxy(t, {})); 
    return proxies.get(t); 
} 

const nodeList = new Proxy(document.querySelectorAll('div'), { 
    get(target, key) { return makeUniqueProxy(target[key]); } 
}); 

const specificNode = makeUniqueProxy(document.querySelector('div[data-target]')); 
//     ^^^^^^^^^^^^^^^ 

for (const node of nodeList) { 
    if (node === specificNode) { doSomethingElse(); } // just works 
} 

這種方法也有非常理想的屬性,nodeList[0] === nodeList[0]

+0

使用WeakMaps跟蹤代理是非常甜蜜的解決方案,謝謝。 – nils