Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.02.2020, 20:51
Аватар для drwhite
Интересующийся
Отправить личное сообщение для drwhite Посмотреть профиль Найти все сообщения от drwhite
 
Регистрация: 16.11.2015
Сообщений: 14

Получить имя функции внутри функции не используя callee
Приветствую, камрады, можно ли сделать как в PHP:
public function func($in_params)
{ 
    $__F__ = __FUNCTION__;
    ...
    if (...) $__F__($in_params);
}

чтобы не зависеть от имени функции, но не используя callee?
Ответить с цитированием
  #2 (permalink)  
Старый 05.02.2020, 22:02
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Пример варианта для window
<script>
function test(name) {
    if (typeof window[name] === "function") {
        window[name]();
    } else {
        alert("Function not declared")
    }
}

function one() {
    alert('One');
}

test("one");
test("two");

</script>
Ответить с цитированием
  #3 (permalink)  
Старый 06.02.2020, 03:40
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Poznakomlus, пишут ведь, что «чтобы не зависеть от имени функции». Ещё ваш вариант предполагает засорение глобального объекта, а также его изменение! Также у вас не соблюдена чистота функции. Также вы не показали, как получить функцию внутри функции не используя callee!

drwhite, в JavaScript как раз для этого и есть arguments.callee, который указывает на функцию.

Однако стоит учитывать, что по имени функции не всегда возможно обратиться к самой функции, поэтому лучше говорить о ссылке на функцию.
function factorial(n) {
    if(n % 1 !== 0 || n < 0) throw Error("n ∈ Z ⋀ n ≥ 0");
    if(n === 0) return 1;
    return n * arguments.callee(n - 1);
}

alert(factorial(5)); // 5! = 120


Однако, если вы вдруг решили, что вам по каким-то причинам arguments.callee не подходит (по каким?), то вы можете использовать Y-комбинатор!

var Y =
  f => (
      g => x => f(g(g))(x)
    )(
      g => x => f(g(g))(x)
    );

var factorial = Y(fn => n => {
    if(n % 1 !== 0 || n < 0) throw Error("n ∈ Z ⋀ n ≥ 0");
    if(n === 0) return 1;
    return n * fn(n - 1);
});

alert(factorial(5)); // 5! = 120
Обращение функции к самой себе вообще не предполагает наличие глобальной ссылки. Т. е. поскольку она не называет себя по имени, она не связана тесно с самой собой.

Последний раз редактировалось Malleys, 06.02.2020 в 03:46.
Ответить с цитированием
  #4 (permalink)  
Старый 06.02.2020, 08:39
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,075

может я что-то не понимаю, но альтернативы arguments.callee в решениях выше Poznakomlus и
Malleys
не увидел.
Ответить с цитированием
  #5 (permalink)  
Старый 06.02.2020, 10:29
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,504

Потому что её нет.
Если вы работаете в нестрогом режиме - у вас уже есть arguments.callee, никакого смысла в чём-то ещё нет.
Если вы работаете в строгом режиме - arguments.callee у вас отобрали специально, чтобы заметно ускорить и облегчить исполнение избавившись от сложных взаимосвязей и побочек. Альтернативы, соответственно, тут принципиально не будет.
__________________
29375, 35
Ответить с цитированием
  #6 (permalink)  
Старый 06.02.2020, 10:48
Аватар для drwhite
Интересующийся
Отправить личное сообщение для drwhite Посмотреть профиль Найти все сообщения от drwhite
 
Регистрация: 16.11.2015
Сообщений: 14

Сообщение от Malleys
Однако, если вы вдруг решили, что вам по каким-то причинам arguments.callee не подходит (по каким?)
Именно потому, что оно устаревшее и вообще я за стрикт моде.

Сообщение от Malleys
можете использовать Y-комбинатор!
«— Будете у нас на Колыме…
— нет, уж лучше вы к нам» =)

Сообщение от Aetae
в строгом режиме - arguments.callee у вас отобрали специально, чтобы заметно ускорить и облегчить исполнение избавившись от сложных взаимосвязей и побочек
Но ведь так удобно не зависеть от имени функции при рекурсии. Чем, кстати, оно может нагадить?
Ответить с цитированием
  #7 (permalink)  
Старый 06.02.2020, 11:10
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от рони
альтернативы arguments.callee в решениях выше Poznakomlus и
Malleys не увидел.
В моём втором примере показазан Y-комбинатор.

Сообщение от Aetae
Альтернативы, соответственно, тут принципиально не будет.
Сообщение от drwhite
Но ведь так удобно не зависеть от имени функции при рекурсии.
Y-комбинатор делает именно то, что вы хотите. Или что вы имеете в виду, когда пишете «не зависеть от имени функции при рекурсии»?
Ответить с цитированием
  #8 (permalink)  
Старый 06.02.2020, 11:18
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,075

Сообщение от Malleys
Y-комбинатор делает именно то, что вы хотите. Или что вы имеете в виду, когда пишете «не зависеть от имени функции при рекурсии»?
для меня Y-комбинатор, выглядит как вместо имени функции будем использовать имя функции
Ответить с цитированием
  #9 (permalink)  
Старый 06.02.2020, 12:08
Аватар для drwhite
Интересующийся
Отправить личное сообщение для drwhite Посмотреть профиль Найти все сообщения от drwhite
 
Регистрация: 16.11.2015
Сообщений: 14

Сообщение от Malleys
Y-комбинатор делает именно то, что вы хотите. Или что вы имеете в виду, когда пишете «не зависеть от имени функции при рекурсии»?
хочу как-то так:
function func($params)
{
    ...
    if (...) self($params);
}


чтобы имя функции указывалось один раз, без лишних переменных, без NFE и в strict mode =)
Ответить с цитированием
  #10 (permalink)  
Старый 06.02.2020, 12:38
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

<script>
function test() {
    try {
        throw  new Error( "Get name")
    } catch (e) {
        console.log(e.stack);
    }
}
test();
</script>

название функции есть в стеке вызовов, однако этот стек по разному работает в броузерах
если я вас правильно понял
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Узнать имя функции Bercut Общие вопросы Javascript 27 25.12.2020 08:02
как правильно передвать имя radiobutton в функции boris2000 Элементы интерфейса 2 03.08.2010 21:16
Как получить имя файла и изменить его? nedosalivan Общие вопросы Javascript 5 29.03.2010 17:51
Как получить имя компа через JavaScript? Бурундук Общие вопросы Javascript 3 19.09.2009 16:44
Можно ли получить имя экземпляра объекта внутри самого объекта? Ichigeki Общие вопросы Javascript 9 14.11.2008 19:00