ajvincent / es-membrane

An ECMAScript implementation of a Membrane, allowing users to dynamically hide, override, or extend objects in JavaScript with controlled effects on the original objects.
111 stars 13 forks source link

Standard distortion type: Clean-up observer patterns when a Proxy is revoked (ex: addEventListener) #217

Open ajvincent opened 5 years ago

ajvincent commented 5 years ago
<html>
<head>
  <title></title>
  <meta charset="UTF-8">
</head>
<body>
  <button id="foo">Hello</button>
  <button id="revoke" onclick="revoke();">Revoke</button>
</body>
</html>
function fooHandler() {
  console.log("fooHandler");
}

const {proxy: fooProxy, revoke: fooRevoke} = Proxy.revocable(fooHandler, Reflect);
var revoke, foo;
{
   let revoked = false;
   revoke = () => {
     if (revoked)
       return;
     revoked = true;
     fooRevoke();
     foo.removeEventListener("click", fooProxy, true);
   }
}

window.onload = function() {
  foo = document.getElementById("foo");
  foo.addEventListener("click", fooProxy, true);
};

If we called fooRevoke() directly without revoke(), then anytime we clicked the foo button, we'd trigger an exception for the revoked proxy.