Получить имя функции, подобное напечатанному в консоли Chrome

Учитывая этот код:

var o = {};
o.f = function(){};
new o.f;

Хромовые принты o.f {} в консоль. Ты знаешь как это o.f часть называется? Что еще более важно, есть ли способ получить этот результат без использования консоли? Я хотел бы извлечь имя метода из самой функции, то есть без какой-либо дополнительной информации.

Я уже знаю, как получить имя в этом случае:

function f(){}
f+'' // "function f(){}"

Но это не ведет себя так же, как в ситуации, описанной выше.


Следующее содержание в основном скопировано из комментариев.

Я хотел знать, есть ли "техническое" слово, чтобы поговорить об этом o.f шаблон, скажем, например, "пространство имен", "идентификатор" или "путь к функции". Затем мне стало интересно, есть ли способ извлечь эту информацию из загруженного скрипта на веб-странице. Следующий вопрос может помочь вам понять мою цель, абзац, который находится сразу после первого блока кода, очень близок моей идее: сохраняет ли Chrome конструктор каждого объекта?,

Возможно, я должен был упомянуть, что моей первоначальной целью было создание документации во время выполнения: / В этом случае было бы полезно что-то вроде API отражения. Точнее, я искал способ включить имя метода в декомпилированную форму функции. Посмотрите:

function Class(){}
Class.prototype.method = function(){};

Class.prototype.method + '' дает function(){}, Я хотел бы ввести имя метода, чтобы получить этот результат: function method(){},

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

3 ответа

Решение

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

o.f = function(){};

это общее утверждение, состоящее из еще более распространенных выражений. o.f это просто один из двух способов доступа к свойствам объектов, обычно называемых точечной нотацией. Хотя я верю в JS, точка (.) На самом деле не рассматривается как оператор, и впредь я буду называть ее оператором-членом.
Далее у нас есть известный оператор присваивания, который назначает правый операнд слева (член объекта o, называется f).
Правое выражение (должно быть оценено как единичное значение) - это определение функции, которое вместо отдельного оператора используется в качестве выражения. Учитывая этот факт, мы называем это использование функций как выражения функций.

В данном конкретном случае у функции нет имени, это анонимная функция. Внутренне большинство - если не все двигатели - дадут ему имя, но это не то, что JS должен знать или действительно беспокоиться. Что касается JS, эта функция не имеет имени и доступна только через o.f, Если вы вызываете эту функцию так: o.f() его контекст будет контекстом объекта o эффективно заставляя эту функцию вести себя как метод.
Таким образом, в основном ваше утверждение звучит так: "Назначьте и создайте, если необходимо, члену o называется f , анонимная функция." Сама функция не имеет имени.

Учти это:

var o = {f: function(){console.log('I am a function');}};
var foobar = o.f;
foobar();//logs I am a function

Так сказать название функции o.f является f не всегда применяется. Другие переменные или свойства могут ссылаться на ту же функцию. Это потому, что функции являются объектами первого класса, они могут быть возвращены, переданы и назначены, из чего угодно и чем угодно.

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

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

f.o = function newName(){};

newName имя, кроме старых версий IE, недоступно за пределами области действия функций. Это требуется спецификациями ECMA, см. Подробности здесь. Во всяком случае, теперь мы можем проверить это:

var func = function func(){console.log(func);};
//same name:
func();//logs function func(){}
var foobar = func;
foobar();//logs function func(){}
func = 123;//<-- no longer function
foobar();//still function func(){}//func is still accessible
var hidden = (function()
{
    return function named()
    {
        console.log(named);//access name
    };
}());
hidden();//logs function named(){}
console.log(named);//undefined -> not visible outside the function itself

Имя функции ограничено ее собственной областью действия.

Используйте регулярное выражение, которое немного хакерское и не использует две переменные / свойства, ссылающиеся на один и тот же объект функции:

o = {f: function(){console.log('I am a function');}};
for (var pName in o)
{//probably add o.hasOwnProperty(pName) check to be safe
    if (o[pName] instanceof Function)
    {
        console.log(o.f.toString().replace(
            /^function\s*\(/,
            'function o.'+pName+'(')
        );
    }
}

Это приводит в порядок функцию (давая function (){/*body*/}) и заменяет function ( с function <propertyName>(, Если у функции уже было собственное имя, это имя не заменяется.

В общем, это не распространенная практика в Javascript или в программировании в целом.

Тем не мение, functionУ них есть имя атрибута - см. Function.name. но в вашем коде o.f это безымянная функция.

var o = {};
o.f = function(){}; //function (){} creates a nameless function.

Вы можете определить имя до ()

var o = {};
o.f = function f(){}; //function f(){} creates a function with the name f

затем

o.f.name == 'f'

ПРИМЕЧАНИЕ: эта функциональность НЕ поддерживается в IE и не является спецификацией EMCA.

Это выставлено как name свойство функции, и в наши дни она является частью стандарта (поиск SetFunctionName в спецификации). См. Также MDN, Chrome Platform Status, поддержка браузера. Если вы спрашиваете конкретно о функции автоматического угадывания имени из имени переменной для анонимных функций, MDN вызывает это имя выведенной функции.

Назад, когда вопрос был задан, окончательным обсуждением этой темы была статья kangax: " Названные выражения функций демистифицированы (теперь немного устаревшие).

Другие вопросы по тегам