WedX - журнал о программировании и компьютерных науках

Получить имя метода из метода машинописного текста

Я хочу получить имя текущего метода из экземпляра метода класса в Typescript.

(Псевдокод, не работает):

class Foo {
    bar() {
        console.log(something); //what should something be?
    }
}

new Foo().bar();

Я ожидаю, что «что-то» вернет «бар». Я понимаю, что this может дать мне класс, и я мог бы каким-то образом получить от него класс и его атрибуты, но я не знаю, как получить «эту функцию» (т.е. панель методов, а не класс Foo).

Я видел несколько других вопросов, связанных с поиском имени класса и т. Д., Но не тот, который касается получения текущего имени метода.

17.08.2017

  • зачем вам знать название метода? Вы называете это, чтобы знать имя. 17.08.2017
  • это не совсем машинописный вопрос ... :) 18.08.2017
  • @Rienk - я пытаюсь сделать что-то более сложное (в частности, поведение ruby ​​method_missing в машинописном тексте), но в качестве более простого примера предположим, что у меня есть устаревший код с (большим количеством методов), такими как getFoo() и getBar(), и я хочу обработать все это с использованием функции getObject(objName), которая анализирует имя функции и возвращает объект из словаря по имени. Я хочу вызывать getObject(thisFuncName) в каждой такой функции вместо того, чтобы изменять каждую такую ​​функцию, чтобы говорить такие вещи, как getObject('foo') и т. Д. 18.08.2017
  • Ананд: затем откройте новый вопрос с шаблоном, которого вы хотите достичь с помощью TypeScript. Думаю, так будет лучше. Как сказал @Kokodoko, это не TypeScript, а JavaScript. 18.08.2017
  • Есть arguments.callee.name, но он не работает в строгом режиме, а методы класса выполняются в строгом режиме. Вы можете попробовать использовать для этого Proxy , но не все браузеры поддерживают прокси. 18.08.2017
  • @Kokodoko Я добавил тег javascript 18.08.2017
  • @lilezek - это довольно распространенная функция в динамических языках - ruby ​​предоставляет __method__ для возврата имени текущего метода из каждого метода - см. stackoverflow.com/questions/199527/ 18.08.2017
  • вы можете вызвать функцию с параметризованным именем (я думаю): var instance = new Foo (); экземпляр [methodNameParameter] (); 18.08.2017

Ответы:


1

Помимо arguments.callee.name простой способ получить это.

Предлагаю еще 2 метода:

Используйте декораторы, чтобы ввести имя метода:

function annotateName(target, name, desc) {
    var method = desc.value;
    desc.value = function () {
        var prevMethod = this.currentMethod;
        this.currentMethod = name;
        method.apply(this, arguments);
        this.currentMethod = prevMethod;   
    }
}

class Foo {
    currentMethod: string;

    @annotateName
    bar() {
        alert(this.currentMethod);
        this.tux();
        alert(this.currentMethod);
    }

    @annotateName
    tux() {
        alert(this.currentMethod);
    }
}

new Foo().bar();

Обратной стороной является то, что вам нужно аннотировать все функции, от которых вы хотите получить имя. Вместо этого вы можете просто аннотировать класс, а в декораторе перебрать все функции-прототипы и применить ту же идею.


Мой второй вариант не стандартизирован и требует большей осторожности, чтобы получить согласованные результаты в разных браузерах. Он полагается на создание объекта Error и получение его стека след.

class Foo {
    bar() {
        console.log(getMethodName());    
    }
}

function getMethodName() {
    var err = new Error();
    return /at \w+\.(\w+)/.exec(err.stack.split('\n')[2])[1] // we want the 2nd method in the call stack

}

new Foo().bar();
17.08.2017

2

Не уверен, что это поможет, но:

class Foo {
    bar() {
        console.log(Object.getOwnPropertyNames(Foo.prototype)); // ["constructor", "bar"]
    }
}

new Foo().bar();

17.08.2017

3

Имейте в виду, что во время компиляции и минификации вы можете потерять фактическое имя того, что пытаетесь использовать. Вы можете изучить макрос babel ts-nameof, который считывает имя практически всего во время компиляции. и возвращает его фактическое строковое представление.

21.05.2020

4

для имени класса - Foo.name для имени метода - this.bar.name

07.02.2019
  • Вопрос заключался в том, как получить имя выполняемого в данный момент метода. 01.05.2019

  • 5

    Чтобы ответить на вопрос еще одним интересным вариантом, вы можете сделать (но не должны) что-то вроде этого:

    class Foo {
        constructor(private http: HttpClient) {
    
            const apiUrl = 'https://myapi.com/api/';
    
            {
                const functionName = 'getBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
    
            {
                const functionName = 'postBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
    
            {
                const functionName= 'putBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
    
            {
                const functionName= 'deleteBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
        }
    }
    

    Это определенно не изящное решение, и я не могу представить себе хороший вариант использования для чего-то подобного, поскольку я почти уверен, что компилятор не распознает new Foo(http).deleteBar(). Может быть, кто-то сможет придумать изящное решение с этой идеей, я оставлю это как эксперимент для кого-то.

    Но с этим шаблоном (если вы используете какие-то строительные леса DevOps или «сильные навыки копирования и вставки») вы всегда можете получить доступ к имени вашего метода через functionName

    21.05.2020

    6

    Я тоже искал решение, попробуйте следующее:

    class Foo {
      bar() {
          console.log(this.bar.name); // <-- Print out the function name.
      }
    }
      
    new Foo().bar(); 
    

    Приятно то, что вы получите сообщение об ошибке, если измените имя функции, но забудете обновить оператор консоли.

    20.01.2021
  • но this.bar.name длиннее, чем просто набирать bar. 24.04.2021
  • Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]