title: Using ES6 Proxies to hide private properties
body: <p>I'm trying to create a function that hides private properties on Objects as well as possible. I would define private properties here as those that begin with an underscore, eg. <code>_password</code>.</p>
  
  <p>Below is what I've got so far (thanks to <a href="https://ponyfoo.com/articles/es6-proxies-in-depth" rel="nofollow noreferrer">Nicolas Bevacqua's great intro to proxies</a>).</p>
  
  <p>Now I was wondering:</p>
  
  <ol>
  <li>Am I covering all bases with the following code? Or am I missing an important proxy trap through which the objects could still be accessed?</li>
  <li>Is this the right way to use the <code>Reflect</code> methods in conjunction with a proxy? And do I even need them here?</li>
  <li>Are the values I return for private properties real enough to let people think that the property really does not exist?</li>
  </ol>
  
  <p>My function so far:</p>
  
  <pre><code>function privatize(obj, prefix = '_', throwError = false) {
    const proxyHandler = {
      get(target, key) {
          return private(key, 'get') ? undefined : Reflect.get(target, key);
        },
        set(target, key, value) {
          return private(key, 'set') ? undefined : Reflect.set(target, key, value);
        },
        has(target, key) {
          return private(key, 'has') ? false : Reflect.has(target, key);
        },
        deleteProperty(target, key) {
          return private(key, 'delete') ? false : Reflect.deleteProperty(target, key);
        },
        defineProperty(target, key, descriptor) {
          return private(key, 'defineProperty') ? false : Reflect.defineProperty(target, key, descriptor);
        },
        enumerate(target) {
          return Object.keys().filter((key) =&gt; {
            return !private(key, null, false);
          })[Symbol.iterator]();
        },
        ownKeys(target) {
          return Reflect.ownKeys(target).filter((key) =&gt; {
            return !private(key, null, false);
          });
        },
        getOwnPropertyDescriptor(target, key) {
          return private(key, 'getOwnPropertyDescriptor') ? false : Reflect.getOwnPropertyDescriptor(target, key);
        }
    };
  
    function private(key, operationName) {
      if (key.indexOf(prefix) === 0) {
        if (throwError) {
          throw new Error(`Operation '${operationName}' is not allowed on private properties.`);
        }
        return true;
      }
    }
  
    return new Proxy(obj, proxyHandler);
  }
  
  var o = {
    first: 'should work',
    _second: 'should fail'
  };
  
  var proxied = privatize(o);
  
  console.log(proxied);
  </code></pre>
  
  <p>PS: For native browser support, you might have to look at it in MS Edge or Firefox Dev Edition.</p>
  
  <p><a href="http://jsfiddle.net/bkd7mde7/1/" rel="nofollow noreferrer">http://jsfiddle.net/bkd7mde7/1/</a></p>