Function.prototype.new

Maybe an example about how this proposal makes everything better for everyone would work ...

How it is now

<!DOCTYPE html>
<head>
  <script>
    const traps = {
      construct(target, args) {
        console.log('construct');
        return Reflect.construct(target, args);
      },
      get(target, name) {
        console.log('get', name);
        if (
          // guessing + pretending
          // still error prone
          name === 'new' &&
          typeof target === 'function' &&
          !('new' in target)
        ) {
          return (...args) => traps.construct(target, args);
        }
        // fallback
        return target[name];
      }
    };

    // example code: foreign class + pyodide proxy
    class Thing {}
    const $Thing = new Proxy(Thing, traps);
    console.log($Thing.new());
  </script>
</head>
</html>

How it could be instead

<!DOCTYPE html>
<head>
  <script src="https://unpkg.com/@ungap/new"></script>
  <script>
    // this is literally it:no magic guessing or pretending
    const traps = {
      construct(target, args) {
        console.log('construct');
        return Reflect.construct(target, args);
      },
      get(target, name) {
        console.log('get', name);
        return target[name];
      }
    };

    // example code: foreign class + pyodide proxy
    class Thing {}
    const $Thing = new Proxy(Thing, traps);
    console.log($Thing.new());
  </script>
</head>
</html>

Moving parts, possible shenanigans, guessing ... all gone: it just works out of Proxy primitives which makes it easier to maintain and reason about.

In a real-world scenario though, the get trap is way more complicated because of namespaces ... so let's see how a complete trap could look like (considering previous complexity on top without Function.prototype.new):

<!DOCTYPE html>
<head>
  <script src="https://unpkg.com/@ungap/new"></script>
  <script>

    function get(target, name) {
      console.log('get', name);
      const value = target[name];
      switch (typeof value) {
        case 'function': return new Proxy(value, cbTraps);
        case 'object': if (value) return new Proxy(value, objTraps);
        default: return value;
      }
    }

    const cbTraps = {
      construct(target, args, proxy) {
        console.log('construct', proxy);
        return Reflect.construct(target, args);
      },
      apply(target, self, args) {
        console.log('apply', self /* is proxy */);
        return target.apply(self, args);
      },
      get
    };

    const objTraps = { get };

    // example code w/ namespace
    class Thing {}
    const { some } = new Proxy({ some: { Thing }}, objTraps);
    console.log(some.Thing.new());
  </script>
</head>
</html>

Nowhere in my examples I need to branch out regular logic or consider special meaning for any property or do anything different from what I'd do regularly with JS ... and this is the reason I am proposing Function.prototype.new unless anyone can show me code that doesn't guess, never fails and is also easier or less complicated than just this one.

I don't think I have anything else to add but please, please, try to be a tiny bit open minded around this request: it would simplify and normalize by far interoperability with any present to future foreign PL dealing with JS: thank you!