Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Получить имя функции внутри функции не используя callee (https://javascript.ru/forum/misc/79421-poluchit-imya-funkcii-vnutri-funkcii-ne-ispolzuya-callee.html)

рони 06.02.2020 14:42

Цитата:

Сообщение от Malleys
Я думаю, саму идею, для чего и как его использовать вы поняли... Вот, например, сортировка...

ценю ваш тонкий юмор.

drwhite 06.02.2020 17:20

Цитата:

Сообщение от Malleys
Вуаля! Рабочая betterRecursive! drwhite, это именно то, что вы хотели!

Благодарю, все верно, но так хотелось сделать это в одну строчку кода)

Цитата:

Сообщение от Alexandroppolus
какова вообще задача? то есть, нафига нужен такой изыск?

Примерно такая же, как и в случае с this и __construct для класса — не надо явно использовать имя, которое может взять и поменяться.
Может быть это и изыск, но, согласитесь, удобнее)

Vlasenko Fedor 06.02.2020 17:25

Цитата:

Сообщение от drwhite
Может быть это и изыск, но, согласитесь, удобнее)

никакого здезь удобства нет, а говорит о неправильном подходе реализации, что в результатке выташили Крокфорда за уши :)

drwhite 06.02.2020 18:09

Цитата:

Сообщение от Poznakomlus
никакого здезь удобства нет, а говорит о неправильном подходе реализации

Разве не удобней обращаться объекту к самому себе через ссылку, которая всегда сработает, а не через придуманное имя?

Зачем тогда придумали слово constructor вместо имени класса?

И какой подход к реализации был бы правильным?

Vlasenko Fedor 06.02.2020 18:34

<script>
function factorial(x)
{
    var result = 1;
    while (x > 1) result *= x--;
    return result;
}
alert(factorial(5));
</script>

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

"И какой подход к реализации был бы правильным?"
тот, который понятен другим разработчикам. Чтобы они не ломали голову в раскручивани вызовов ваши функций. Код должен быть простым и понятым

drwhite 06.02.2020 19:36

Цитата:

Сообщение от Poznakomlus
конструктор служит для иницииализации

Ну хорошо, а если бы вместо this надо было бы использовать имя класса?)

Цитата:

Сообщение от Poznakomlus
честно, полноту вашей задачи я до сих пор не понял

Бывает иногда нужно передать из функции ее имя в другое место, без генерации исключения и раскрутки стека. В пхп есть __FUNCTION__, что очень удобно. Не найдя такого в JS, пришлось зайти на форум и спросить, а вдруг кто-то подскажет.

Цитата:

Сообщение от Poznakomlus
"И какой подход к реализации был бы правильным?"
тот, который понятен другим разработчикам. Чтобы они не ломали голову в раскручивани вызовов ваши функций

Неужто возможность получить имя функции внутри функции кому-то так уж сломает голову?

Скорей Y-комбинатор и замыкания вынесут моск))

PS И потом, как сделать, чтобы код был понятен другим разработчикам, прочитать много умных книг, сходить на разные «курсы», которых сейчас расплодилось как собак нерезаных? Это, положим, можно, есть ли там стандарты и правила написания правильного кода, как узнать?

SuperZen 06.02.2020 20:11

Цитата:

Сообщение от drwhite (Сообщение 519721)
стандарты и правила написания правильного кода, как узнать?

только эмпирическим путем, потому что в книге не будет написано про ту задачу, которую надо сделать. надо тогда на typescript заходить, чтобы все было квадратно. тогда придется изучать другие конструкции и не пытаться доковыряться до ассемблера на жаваскрипте )

Vlasenko Fedor 06.02.2020 21:58

class Test1 {}
class Test2 {
    get name(){ return this.constructor.name}
}
const Test3 = function () {}

const Test4 = function () {
    this.name =()=> this.constructor.name
}
const a = new Test1();
const b = new Test2();
const c = new Test3();
const d = new Test4();
console.log(a.constructor.name);
console.log(b.constructor.name);
console.log(c.constructor.name);
console.log(d.constructor.name);
console.log(b.name);
console.log(d.name());
console.log(Test1.name);

не знаю, может это поможет

Aetae 06.02.2020 22:49

Malleys, просто пишет чушь ради чуши.

Например хипстерское дерьмо, типа:
const factorial = x => {
	if (x === 1)
		return 1;
	else
		return x * factorial(x - 1);
}

alert(factorial(5));
после чего решает проблему которой нет.

Нормальный человек напишет:
function factorial(x) {
	if (x === 1)
		return 1;
	else
		return x * factorial(x - 1);
}
и это будет работать всегда.

Даже если мы потом сделаем так:
function factorial(x) {
	if (x === 1)
		return 1;
	else
		return x * factorial(x - 1);
}

const f = factorial;
alert(f(5));
или так:
// factorial-module.js
function factorial(x) {
	if (x === 1)
		return 1;
	else
		return x * factorial(x - 1);
}

export default factorial;

// main.js
import f from './factorial-module';
alert(f(5));


Если мы хотим пулять функцию по разным переменным сразу после создания, но при этом не хотим засорять область видимости её оригинальным названием(почему?), то всегда можно сделать так:
const factorial = function fcallee(x) {
	if (x === 1)
		return 1;
	else
		return x * fcallee(x - 1);
}


const f = factorial;
const f2 = factorial;

alert(typeof fcallee);
alert(factorial(5));
alert(f(5));
alert(f2(5));


Нет никакой проблемы и никакого смысла в arguments.callee, и уж точно нет смысла в онанизме от Malleys.

Malleys 07.02.2020 00:08

Цитата:

Сообщение от drwhite
Благодарю, все верно, но так хотелось сделать это в одну строчку кода)

Это универсальная функция, её можно вынести в отдельный файл. Или же использовать готовую библиотеку.

Цитата:

Сообщение от Poznakomlus
никакого здесь удобства нет, а говорит о неправильном подходе реализации

Это говорит о твоём непонимании парадигм программировании — в JS так и так есть функции, отказ от возможностей функционального программирования выглядит как некое цифровое веганство.

Цитата:

Сообщение от Poznakomlus
тот, который понятен другим разработчикам. Чтобы они не ломали голову в раскручивании вызовов ваши функций. Код должен быть простым и понятым

Цитата:

Сообщение от drwhite
Это, положим, можно, есть ли там стандарты и правила написания правильного кода, как узнать?

Это зависит от модели программирования. Например, Poznakomlus ошибочно предполагает, что существует единственно истинный способ записи программы, однако используя разные парадигмы для решения одной и той же задачи, можно прийти к выводу, что императивный код не всегда простой, понятный и краткий. Для императивного кода также свойственна ссылочная непрозрачность.

Цитата:

Сообщение от Poznakomlus
избавится от рекурсии

А почему тогда не нужно избавиться от this, constructor, window? Ваши призывы походят на «нравится, а почему, понять не могу».

Цитата:

Сообщение от Aetae
Malleys, просто пишет чушь ради чуши.

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

Вот, например, более практическая задача, чем вычисление факториалов, на примере которой демонстрируется рекурсия...

Обход всех текстовых узлов в DOM
var Y=f=>(g=>x=>f(g(g))(x))(g=>x=>f(g(g))(x));

var processTextNodes = visit => Y(order => node => {
	if(node != null) node.childNodes.forEach(childNode =>
		childNode.nodeType === Node.TEXT_NODE ? visit(childNode) : order(childNode)
	)
});

var logTextNotes = processTextNodes(console.log);
logTextNotes(document.body);
Poznakomlus, попробуйте избавиться от рекурсии и вы закончите кодом, про который не скажешь, что он, по сравнению с этим — простой, понятный и краткий!

Aetae, то, что вы описали, работает с обычными функциями (и это хорошо!), а не со стрелочными.

Зависит от имени...
const factorial = x => x === 1 ? 1 : x * factorial(x - 1);
Y-комбинатор позволяет убрать такую зависимость...
import { Y } from "combinators-js";
const factorial = Y(f => x => x === 1 ? 1 : x * f(x - 1));


Часовой пояс GMT +3, время: 18:03.