2017-05-05 84 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