xPomaHx
@xPomaHx
1vs9

Как используя синтаксис ES-2015 class создать экземпляр который был бы функцией?

Как используя синтаксис ES-2015 class создать экземпляр который был бы функцией?
То есть чтобы экземпляр мог сам быть вызван принимать аргументы и тд, в потом возвращал то что нужно через toString();
class TestClass{
//
};
let testClass = new TestClass();
testClass(1);
testClass(2);
testClass(3);
testClass+1; // возвращает "1231";
  • Вопрос задан
  • 153 просмотра
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
class TestClass {
  constructor() {
    const self = el => self.data.push(el);
    Object.setPrototypeOf(self, TestClass.prototype);

    self.data = [];

    return self;
  }

  toString() {
    return this.data.join('');
  }
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@eeiaao
Унаследоваться от Function
Ответ написан
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Полноценно можно сделать только используя Proxy, но работать будет только в окружении ES-2015 (большинство актуальных браузеров уже поддерживают)
Не полноценно (зато будет работать в браузерах типа IE) - можно сделать через хак предложенный 0xD34F с возвратом своего объекта (функции) из конструктора

Пример с Proxy:
const TestClass = (function() {
    class TestClass {
        constructor() {
            this.calls = '';
        }

        toString() {
            return this.calls;
        }
    }

    Object.setPrototypeOf(TestClass.prototype, Function.prototype);

    function callTestClassInstance(el) {
        this.calls += String(el);
    }

    return new Proxy(TestClass, {
        construct(TestClass, args) {
            const instance = new TestClass(...args);
            const target = args => callTestClassInstance.apply(instance, args);
            Object.setPrototypeOf(target, TestClass.prototype);
            return new Proxy(target, {
                apply(target, _, args) {
                    return target(args);
                },
                get(_, name) {
                    return instance[name];
                },
                set(_, name, value) {
                    instance[name] = value;
                    return true;
                },
                has(_, name) {
                    return name in instance;
                },
                deleteProperty(_, name) {
                    return delete instance[name];
                },
                defineProperty(_, name, descriptor) {
                    return Object.defineProperty(instance, name, descriptor);
                },
                getOwnPropertyDescriptor(_, name) {
                    return Object.getOwnPropertyDescriptor(instance, name);
                },
                ownKeys() {
                    return Object.getOwnPropertyNames(instance).concat(Object.getOwnPropertySymbols(instance));
                }
            });
        }
    });
})();
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы