0

Okay I'm not sure what would you call this or what i should've used in title but what I'm trying to do is a class instance if called be one of the methods by default something like

class Something {
    method() {}
    another() {}
}

const instance = default(new Something(), "method");
instance(); // calls Something.prototype.method
instance.another(); // everything else should still exist

It would be something like cloning the whole prototype in a function object or something, i can't really think right now, Thanks in advance.

Free TNT
  • 61
  • 1
  • 3
  • 9
  • It's not quite clear what you want to have happen here. Do you mean to define a `static` method that can be called like `Something.method()`? – tadman Sep 25 '18 at 18:10
  • You *can* do this a few ways now in JavaScript, but you shouldn’t. What makes it necessary here? – Ry- Sep 25 '18 at 18:13
  • @tadman not a static method, i just wanna wrap the whole instance prototype inside a function that the function is also a piece of the class, something like callable class instance that by default calls one of the instance method i choose – Free TNT Sep 25 '18 at 18:14

1 Answers1

2

No, you cannot call an instance unless it is a function. There is no default function that makes anything callable. You would need to do

class Something {
    constructor() {
        return Object.setPrototypeOf(() => {
            // console.log("instance() was called")
        }, new.target.prototype);
    }
    method() {
        // console.log("instance.method() was called")
    }
    another() {}
}

to get a callable instance from new Something. And yes you could make that arrow function (that is currently empty) dispatch to .method(), but you could as well just place the behaviour right in there.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I thought you couldn't return anything in constructor? And yes i know i can't call an instance so what i was thinking is like const fn = new Class().fn; clonePrototype(Class, fn); so you still have all prototype methods in a function – Free TNT Sep 25 '18 at 18:16
  • It might help to note that `Object.setPrototypeOf()` returns the first parameter after modifying its `prototype`, since people who aren't familiar with this would probably not be able to guess that. – Patrick Roberts Sep 25 '18 at 18:17
  • 1
    @FreeTNT Yes you still can return something from a constructor, and when it's an object it overrides the result value of the `new` expression – Bergi Sep 25 '18 at 18:18
  • @FreeTNT that is not true. If you don't return anything, then the `constructor` implicitly returns `this`, but if a `return` exists in the constructor and its expression is an object, that will be returned instead. – Patrick Roberts Sep 25 '18 at 18:18
  • 1
    @PatrickRoberts I would hope people have to look up `Object.setPrototypeOf` and will also notice [the big red warning](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf) I put there :-) – Bergi Sep 25 '18 at 18:19
  • @Bergi you're the one that wrote that? o: – Patrick Roberts Sep 25 '18 at 18:19
  • @PatrickRoberts [Not exactly](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf$compare?to=510257&from=505441), but [I contributed to it](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf$compare?to=830567&from=776431) – Bergi Sep 25 '18 at 18:23
  • Oh thanks guys, returning a Object.setPrototype(this.method, this.constructor.prototype); works to make the instance be callable and still being able to access other methods just what i needed. – Free TNT Sep 25 '18 at 18:30
  • @FreeTNT No, that doesn't work, that makes every instance *be* `Something.prototype.method`. If you use `return`, you need to create *new* objects on every constructor run. I'd suggest to use [this helper](https://stackoverflow.com/a/36871498/1048572) and write `class Something extends ExtensibleFunction { constructor() { super((...args) => this.method(...args)); } … }`. – Bergi Sep 25 '18 at 18:34