Search code examples
javascriptecmascript-6es6-proxy

Detecting when an object called is called by . accessor or as function call


I have the following object

let o = {
    fn:()=>1,
    a:2
}

if i say o() i want the call to be proxied to fn and if i say o.a the value of a should be returned, is it possible exactly as it is presented?

its more like having an unnamed default function for an object


Solution

  • Since functions in JS are objects, you can extend them with properties:

    const o = Object.assign(() => o.fn(), {
      a: 5,
      fn: () => 1
    });
    
    console.log(o());
    console.log(o.a);

    If you need to overwrite non-writable Function properties, such as name, you can 1st create the function, and then use Object.defineProperties() to add properties, and change non-writables to writables.

    Note: This feels hackish enough, without missing with the Function's non-writable properties. I recommend avoiding it.

    const o = () => o.fn();
    
    Object.defineProperties(o, {
      fn: { value: () => 1 },
      a: { value: 5 },
      name: { writable: true, value: 'whatever' },
    });
    
    console.log(o());
    console.log(o.a);
    console.log(o.name);