Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Узнать имя функции (https://javascript.ru/forum/misc/4895-uznat-imya-funkcii.html)

Bercut 28.08.2009 11:35

Узнать имя функции
 
Возможно ли, находясь внутри функции, получить её имя?

Tim 28.08.2009 11:51

конечно, писать в каждой функции, внутри которой вы можете находиться var name='имя функции';

JSprog 28.08.2009 11:53

arguments.callee

Dmitry A. Soshnikov 28.08.2009 11:57

В Мозилльной реализации, есть свойство .name, в остальных случаях, можно (если функция не анонимная) через .toString() + RegExp.

Цитата:

Сообщение от JSprog
arguments.callee

Это ссылка функции внутри на саму себя, а не имя.

Kolyaj 28.08.2009 12:01

function test() {
        alert(23);
    }
    function getFnName(fn) {
        return fn.toString().match(/function ([^(]*)\(/)[1];
    }
    alert(getFnName(test));

Нужно учитывать, что у функции может не быть имени.

Kolyaj 28.08.2009 12:01

Цитата:

Сообщение от Dmitry A. Soshnikov
Это ссылка функции внутри на саму себя, а не имя.

Хотя ему, скорее всего, и не нужно имя.

Bercut 28.08.2009 12:09

Мне нужно узнать именно имя

Грубо говоря

function test() {

    alert( [некое_выражение_которое_вернёт:test] );

}

Dmitry A. Soshnikov 28.08.2009 14:45

Цитата:

Сообщение от Bercut
Мне нужно узнать именно имя

Ну написали же уже Вам - и алгоритм и, даже, решение. В чём проблема?

Bercut 01.09.2009 23:33

Цитата:

Сообщение от Dmitry A. Soshnikov (Сообщение 28570)
Ну написали же уже Вам - и алгоритм и, даже, решение. В чём проблема?

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

судя по всему решения не существует

Kolyaj 01.09.2009 23:36

function someFunction() {
    alert(getFnName(arguments.callee));
}


Хотя бред какой-то, узнавать имя функции внутри нее самой.

Gvozd 01.09.2009 23:37

Bercut
очень трудно сопоставить между собой два сообщения, и составить общий код?
Цитата:

Сообщение от Dmitry A. Soshnikov
Сообщение от JSprog
arguments.callee
Это ссылка функции внутри на саму себя, а не имя.

Цитата:

Сообщение от Kolyaj
function test() {
alert(23);
}
function getFnName(fn) {
return fn.toString().match(/function ([^(]*)\(/)[1];
}
alert(getFnName(test));
Нужно учитывать, что у функции может не быть имени.


jsru_ 17.03.2014 13:55

function functionName(fun) {
  var ret = fun.toString();
  ret = ret.substr('function '.length);
  ret = ret.substr(0, ret.indexOf('('));
  return ret;
}

andypop 26.07.2014 01:35

function GetRelationShips(){
   var f=arguments.callee;
    RunEndFetch({fn:f})
}
function RunEndFetch(obj){
console.log(obj.fn.name) // GetRelationShips
}

Erolast 26.07.2014 08:07

Ужасное оформление. Какие-то ни о чем не говорящие имена f, obj. Уёб Ужасная отбивка. Названия функций с большой буквы.

Aetae 26.07.2014 08:34

Цитата:

Сообщение от Erolast (Сообщение 322789)
Ужасное оформление. Какие-то ни о чем не говорящие имена f, obj. Уёб Ужасная отбивка. Названия функций с большой буквы.

...да и .name нигде кроме ff не работает. О чём было сказано в этой теме ещё пять лет назад. Нормальное решение задачи было приведено тогда же.

melky 26.07.2014 09:34


andypop 26.07.2014 10:20

Работает еще в nodejs. var f - это переменная. Она может быть любая. Функция это сигнал поэтому с большой буквы.

Erolast 26.07.2014 11:01

Цитата:

var f - это переменная. Она может быть любая.
Да ну? А я-то не знал...
По названиям переменных и функций должно быть четко ясно, для чего они предназначенны. Вот как, скажи, можно понять, что делает функция "RunEndFetch(obj)"?
Цитата:

Функция это сигнал поэтому с большой буквы.
Чо? С большой буквы принято начинать название класса (в жс конструктора), переменные и функции именуются с маленькой.

andypop 26.07.2014 11:40

RunEndFetch - диспатчит сигнал EndFetch и передает ему имя функции и результат фетча в объект для последующей обработки в хэндлере onEndFetch. Я пишу с большой, чтобы отличить запуск сигнала от других функций. Мне так хочется.

Erolast 26.07.2014 12:58

Збс как очевидно.

ixth 27.07.2014 04:40

Цитата:

Сообщение от andypop (Сообщение 322803)
RunEndFetch - диспатчит сигнал EndFetch и передает ему имя функции и результат фетча в объект для последующей обработки в хэндлере onEndFetch. Я пишу с большой, чтобы отличить запуск сигнала от других функций. Мне так хочется.

Привет! Имхо, эвенты, хэндлеры, сигналы, слоты — это все какой-то оверинжиниринг. Все делается гораздо, гооораздо проще:

function FunctionNameExtractorFactoryError () {
	this.name = 'FunctionNameExtractorFactoryError';
}

FunctionNameExtractorFactoryError.prototype = Object.create(Error.prototype);

function FunctionNameExtractorFactory () {
	return this;
}

FunctionNameExtractorFactory.buildFunctionNameExtractorInstance = function () {
	return FunctionNameExtractorFactory.commonFunctionNameExtractor;
};

FunctionNameExtractorFactory.commonFunctionNameExtractor = function (fn) {
	if (!fn instanceof Function) {
		throw new TypeError('argument \'fn\' is not instance of Function');
	}

	if (fn.name) {
		return fn.name;
	} else {
		return FunctionNameExtractorFactory.fallbackFunctionNameExtractor(fn);
	}
};

FunctionNameExtractorFactory.fallbackFunctionNameExtractor = function (fn) {
	if (!fn instanceof Function) {
		throw new TypeError('argument \'fn\' is not instance of Function');
	}

	try {
		var source = (fn.toSource || fn.toString).call(fn);
	} catch (e) {
		if (e instanceof TypeError) {
			throw new FunctionNameExtractorFactoryError('Can\'t get function name due unknown malfunction.');
		} else {
			throw e;
		}
	}

	var match = source.match(/function(?:\s+(.*?))?(?=\()/);
	return match ? match[1] : null;
};

FunctionNameExtractorFactory.prototype.buildFunctionNameExtractorInstance = function () {
	return this.constructor.buildFunctionNameExtractorInstance();
};


Вызывать так:
var functionNameExtractorFactory = new FunctionNameExtractorFactory();
var functionNameExtractor = functionNameExtractorFactory.buildFunctionNameExtractorInstance();
functionNameExtractor(arguments.callee);

MallSerg 27.07.2014 14:02

Изначально наверно имелось в виду имя метода а не имя функции. И скорее всего для того что бы иметь возможность перегрузить этот метод это вроде как зеркалированием называется т.е.
var Obj = {};
Obj.methodName = function functionName (){ retutn Obj }

К сожалению внутри functionName() довольно сложно получить Obj.methodName

А возможность перегружать методы весьма и весьма полезная штука
Ну например есть желание последовательно выполнять кучу анимаций ..
Обычно бля этого используют функции обратного вызова т.е.
Element.moveLefr ({
         speed:10;
         time: 1000;
         success : function (e){
                 e.moveAp ({
                       speed:10;
                       time: 1000;
                       success : function (e){
                           ....... //( и.т.д и.т.п )
                       }
                 })       
         }})

Но если есть возможность перегрузить функции moveLefr и moveAp можно писать проще

Element.moveLefr(10,1000).moveLefr(30,2000)   // и.т.д.


Для этого требуется что бы moveLefr() не выполняла анимацию а просто запомнила свое имя и правильно разместила себя в очереди анимации и вернула объект у которого есть метод moveLefr() т.е. вернула родительский объект у которого определены все методы

melky 27.07.2014 15:15

этот метод, moveLefr, и его вызов, они отвратительны, нет?

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

kobezzza 27.07.2014 15:26

Цитата:

Сообщение от melky (Сообщение 322918)
похоже, что через все попытки сделать нормальный инструмент для анимации, ни у кого это так и не получилось ....

Ну почему, мне кажется, что http://processingjs.org/learning/ сделали хороший инструмент. Никаких уродских колбеков и прочего, язык заточен под написание анимаций и интерактива.

MallSerg 27.07.2014 15:42

Цитата:

Сообщение от melky
этот метод, moveLefr, и его вызов, они отвратительны, нет?

Лично мне не нравятся цепочки callback вызовов особенно когда их больше пары десятков

Тут больше вопрос в том что довольно сложно получить имя метода из самого метода.

Единственный известный мне способ это сравнивание arguments.callee с методами объекта что выглядит довольно ужасно

melky 28.07.2014 11:19

Цитата:

Сообщение от kobezzza (Сообщение 322923)
Ну почему, мне кажется, что http://processingjs.org/learning/ сделали хороший инструмент. Никаких уродских колбеков и прочего, язык заточен под написание анимаций и интерактива.

в "интересные ссылки" кидал ссыль на язык анимации. декларативный

http://motorcortexjs.com/

и... оно тоже косячное

т.е. замешая микстуру из вышеупомянутого двига, processingjs, Web Animations можно сделать что-нибудь интересное. не без косяков, конечно :haha:

Цитата:

Сообщение от MallSerg
Лично мне не нравятся цепочки callback вызовов особенно когда их больше пары десятков

Promise ?

Pinkierar 25.12.2020 01:24

Цитата:

Сообщение от Kolyaj (Сообщение 29234)
Хотя бред какой-то, узнавать имя функции внутри нее самой.

Вот я так использую, почему это плохо?
let item = {
	value: false,
	setItem: function(value) {
		item.value = value;
	},
	checkItem: function(funcName) {
		if (!item.value)
			console.error('Функция "%s" получила не присвоенное значение', funcName);
	},
	add: function(value) {
		item.checkItem(arguments.callee.name);
		item.value = item.value + value;
	},
	subtract: function(value) {
		item.checkItem(arguments.callee.name);
		item.value = item.value - value;
	},
	clear: function() {
		item.checkItem(arguments.callee.name);
		item.value = false;
	},
	getItem: function() {
		item.checkItem(arguments.callee.name);
		return item.value;
	}
};
item.clear();

Функция "clear" получила не присвоенное значение

voraa 25.12.2020 08:02

В строгом режиме не будет работать.
В модулях


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