Javascript имя функции узнать

Получить имя функции в JavaScript

Когда я вызываю метод в объекте obj1, могу ли я каким-либо образом получить имя моей функции (test1) внутри этого метода, кроме синтаксического разбора источника ( this.func.toString() ) функции.

7 ответов

выводит «тест» (в Chrome, Firefox и, вероятно, Safari). Однако arguments.callee.name доступен только из внутри.

Если вы хотите получить имя от вне, вы можете проанализировать его из:

но я думаю, что свойство имени объекта функции может быть тем, что вам нужно:

это, однако, не работает для IE и Opera, поэтому вам остается разбираться в них вручную в этих браузерах.

@Nick Craver: callee объект устарел как свойство Function.arguments , но оставлен как свойство arguments : developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…

@Nick Craver: Я не уверен, почему это не сработает в IE 8, потому что MSDN утверждает, что callee объект доступен с JScript 5.5 (поставляется с IE 5.5): msdn.microsoft.com/en-us/library/334e1zza (VS.85) .aspx

@Daniel Даниель — Во-первых, хороший момент о различении функций. Во-вторых, JScript 5.5 != JavaScript 1.5 , никогда не было . но вы не должны поверить мне на слово. Откройте IE8 и протестируйте его самостоятельно: jsfiddle.net/guxRA

@Nick: О, я знаю, что JScript 5.5 не поддерживает Javascript 1.5. Мне просто интересно, почему arguments.callee.name не будет работать в IE 5.5+. Я протестировал код в IE 6. Действительно, он не работает. Затем я протестировал jsfiddle.net/guxRA/2 и выяснилось , что IE 6 создает исходный код функции в качестве arguments.callee . Как весело.

@Daniel — Да, хорошо, IE . не уверен, почему за это проголосовали, так как это не является жизнеспособным решением проблемы, если только вы не собираетесь игнорировать очень большую аудиторию. Я понимаю, если это не работает в IE6, я даже немного улыбаюсь, но IE7 и IE8 я не думаю, что вы можете игнорировать.

Разобрать его из arguments.callee.toString (). Afaik единственный способ определить именованную функцию в Javascript — это предваряя имя ключевым словом ‘function’, поэтому, вероятно, простой indexOf поможет вам в этом.

Это сработало для меня только тогда, когда я сделал var _ = function()<> , но не function _()[> . UPD: о нет, наоборот.

@Nakilon — когда вы делаете var _ = function () <>, вы создаете анонимную (безымянную) функцию и присваиваете ее переменной с именем _. Функция не может знать или помнить, что она была назначена переменной с таким именем, поэтому проверка имени функции ничего не дает.

FYI function.name является «частью стандарта ECMAScript 2015 (ES6)», поэтому он должен быть ориентирован на будущее (но может работать не везде сегодня). См. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

До ES2015 не было стандартного способа получить имя функции. Большинство современных браузеров поддерживают свойство name на объектах Function , которые были нестандартными до ES2015, но текущая версия IE не работает. Единственный вариант, который вам остается оставить, если вам нужно поддерживать IE, пытается проанализировать имя из представления строки функции, которое не является хорошей идеей. Здесь (длинная) дискуссия об этом: http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/b85dfb2f2006c9f0

@ChrisDutrow: зависит от ваших требований. Проблема в том, что то, что работает в сегодняшнем браузере, может не работать в завтрашнем.

Как? Если история что-то доказала, то все наоборот: сегодня работает только то, что гарантированно будет работать и в завтрашних браузерах. Любой браузер, который изменяется обратно несовместимым образом, ломая существующие веб-сайты, будет совершать самоубийства на рынке.

Вот почему попытки W3C отказаться от таких тегов, как и , потерпели неудачу. По этой же причине такие вещи, как атрибут name в полях формы или выражения типа form.myField.value, все еще работают. Вот почему глупая попытка IANA уничтожить mime-тип text / javascript обречена на провал. Вы не можете устареть / устареть / убить то, что активно используется во всем Интернете.

Популярные фреймворки, такие как Prototype JS, активно используют самоанализ функций через метод toString (). Это практически гарантирует проблемы для браузеров, которые его не поддерживают. Они потеряют долю рынка. ( ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js строка 117)

Если Интернет до сих пор что-то доказал, так это то, что он не любит ломать изменения и не любит фрагментации. Такие вещи, как WAP (для мобильных телефонов) или XHTML значительно потерпели неудачу, поскольку они представляют собой переломные или фрагментарные изменения. Люди не хотят просматривать какую-то суб-сеть. Они хотят служить всемирной паутине и ничего больше. Мобильные браузеры должны поддерживать Prototype JS, jQuery и т. Д., Чтобы иметь шанс получить долю на рынке. Никто не заботится о стандартах, когда они не помогают. И EcmaScript — тот, о ком они меньше всего заботятся. Вот почему мы все продолжаем называть это Javascript. 🙂

@StijndeWitt: Я понимаю вашу точку зрения, но я думаю, что эта нишевая функция интересна только разработчикам. Поставщики браузеров исторически не беспокоились об изменении вывода toString() для функций. Поскольку стандарт является разрешающим и отсутствует консенсус и, следовательно, нет фактического стандарта, не так уж много, чтобы остановить будущие изменения. И при всем уважении к Prototype, это не тот плеер, которым я был, и я не уверен, что выпуск новой версии браузера с строковым форматированием функций, который не был правильно проанализирован Prototype, окажет существенное влияние на популярность браузера.

Источник

Function.name

Read-only свойство name глобального объекта Function и его экземпляров содержит название функции созданное во время определения функции или присваивания ссылки на функцию переменной, свойству, аргументу и т. п. Для анонимных функций это свойство может иметь значение «anonymous» или пустую строку «» .

Интерактивный пример

Интерактивные примеры размещены в GitHub репозитории. Если вы хотите добавить свои примеры, то клонируйте https://github.com/mdn/interactive-examples и пришлите пул реквест.

Атрибуты свойства Function.name
Записываемое нет
Перечисляемое нет
Настраиваемое да

Примечание: Заметьте, что в нестандартном, pre-ES2015 релизе configurable свойство было false

Примеры

Имя объявленной функции

Свойство name возвращает имя функции, либо пустую строку для анонимных функций:

function doSomething() > alert(doSomething.name); // выведет "doSomething" 

Имя функции-конструктора

Функции, созданные синтаксисом new Function(. ) или просто Function(. ) создают Function и имеют name «anonymous»:

(new Function).name; // "anonymous" 

Предполагаемые имена функций

Переменные и методы могут предположить название анонимной функции из её синтаксической позиции (new in ECMAScript 2015).

var f = function() >; var object =  someMethod: function() > >; console.log(f.name); // "f" console.log(object.someMethod.name); // "someMethod" 

Вы можете определить функцию с именем в function expression:

var object =  someMethod: function object_someMethod() > >; console.log(object.someMethod.name); // выведет "object_someMethod" try  object_someMethod > catch(e)  console.log(e); > // ReferenceError: object_someMethod is not defined 

Вы не можете изменить имя функции, это свойство только для чтения:

var object =  // анонимная функция someMethod: function() > >; object.someMethod.name = 'otherMethod'; alert(object.someMethod.name); //someMethod 

Для изменения name можно использовать Object.defineProperty() .

Сокращённые имена методов

var o =  foo()> >; o.foo.name; // "foo"; 

Имена функций после привязки

Function.bind() производит функцию, получающую имя «bound и название самой функции.

function foo() >; foo.bind(>).name; // "bound foo" 

Имена функций для getters и setters

Когда используются get и set, «get» и «set» появятся в имени функции.

let o = < get foo()<>, set foo(x)<> >; var descriptor = Object.getOwnPropertyDescriptor(o, "foo"); descriptor.get.name; // "get foo" descriptor.set.name; // "set foo";

Имена функций-классов

Можно использовать obj.constructor.name чтобы проверить «class» объекта (читайте предупреждение ниже):

function Foo() <> // ES2015 Syntax: class Foo <> var fooInstance = new Foo(); console.log(fooInstance.constructor.name); // logs "Foo"

Предупреждение: Интерпретатор объявит встроенное Function.name свойство только если функция не имеет своего собственного свойства name (см. 9.2.11 of the ECMAScript2015 Language Specification). Однако, в ES2015 статичные методы перезаписывают OwnProperty конструкторов класса-функции (ECMAScript2015, 14.5.14.21.b + 12.2.6.9).

Таким образом, нельзя получить доступ к name любого класса со статичным свойством name():

class Foo  constructor() > static name() > > 

Со static name() методом Foo.name больше не содержит название класса, но отсылает к функции name() . Приведённое выше определение класса в ES2015 будет вести себя в Chrome и Firefox как в ES5:

function Foo() <> Object.defineProperty(Foo, 'name', < writable: true >); Foo.name = function() <>;

Пытаясь получить доступ к fooInstance с помощью fooInstance.constructor.name не даст название класса, но выведет метод name() . Пример:

let fooInstance = new Foo(); console.log(fooInstance.constructor.name); // logs function name()

Из ES5 syntax примера также видно, что в Chrome или Firefox статичное определение Foo.name становится записываемым (writable). Встроенное определение в отсутствии кастомного статичного методадоступно только для чтения:

Foo.name = 'Hello'; console.log(Foo.name); // logs "Hello" if class Foo has a static name() property but "Foo" if not.

Следовательно не ожидайте, что Function.name свойство будет всегда содержать имя класса.

Имена функций-символов

Если у Symbol объявляется имя, то название метода — это имя квадратных скобках.

let sym1 = Symbol("foo"); let sym2 = Symbol(); let o =  [sym1]: function()>, [sym2]: function()> >; o[sym1].name; // "[foo]" o[sym2].name; // "" 

JavaScript минифицированный

Предупреждение: Будьте осторожны, используя Function.name и изменения source кода с помощью JavaScript compressors (minifiers) или обфускаторов. Эти инструменты часто используются, как встроенные в JavaScript build pipeline, чтобы сократить размер билда перед деплоем в production. Такие трансформации часто изменяют имена функций.

function Foo() <>; let foo = new Foo(); if (foo.constructor.name === ‘Foo’) < console.log("'foo' is an instance of 'Foo'"); >else
function a() <>; let b = new a(); if (b.constructor.name === ‘Foo’) < console.log("'foo' is an instance of 'Foo'"); >else

В несжатой версии код выполняется ожидаемо «‘foo’ is an instance of ‘Foo'» . В то время, как в сжатой версии он ведёт себя иначе. Если вы полагаетесь на Function.name , как в примере, то убедитесь, что pipeline не меняет код или не ожидайте от функции определённого имени.

Спецификация Статус Комментарии
ECMAScript 2015 (6th Edition, ECMA-262)
Определение ‘name’ в этой спецификации.
Стандарт Изначальное определение.

Совместимость с браузерами

BCD tables only load in the browser

Found a content problem with this page?

This page was last modified on 17 июл. 2023 г. by MDN contributors.

Your blueprint for a better internet.

Источник

Читайте также:  Docker php ext exif
Оцените статью