Доступ к функции доступа программно

Можно ли в коде получить доступ к свойству ["[[FunctionLocation]]"], которое инструменты разработчика google chrome показывают при использовании консольного журнала функции?

Ответ 1

Ответ пока что нет.

Свойство [[FunctionLocation]], которое вы видите в Инспекторе, добавляется в V8Debugger::internalProperties() в коде отладчика C++, который использует другую функцию C++ V8Debugger::functionLocation() для сбора информации о функция. Затем functionLocation() использует ряд специфичных для V8 API C++, таких как v8::Function::GetScriptLineNumber() и GetScriptColumnNumber(), чтобы узнать точную информацию.

Все API, описанные выше, доступны исключительно для кода C++, а не кода JavaScript. Другими словами, код JavaScript на веб-странице не имеет прямого доступа к этой информации.


Однако вы можете получить доступ к свойствам с помощью расширения Chrome. Позже в движке JavaScript V8, используемом Chrome, была добавлена поддержка доступа к этим свойствам через протокол Chrome DevTools. В частности, вы можете получить внутренние свойства с помощью вызова Runtime.getProperties. Кроме того, кажется, что расширения Chrome могут взаимодействовать с протоколом DevTools через chrome.debugger.

Подтверждение концепции использования протокола DevTools в Node.js, который имеет прямой доступ к протоколу с помощью встроенного модуля Inspector (полезно упомянутое Мохамедом в их ответе):

global.a = () => { /* test function */ };

const s = new (require('inspector').Session)();
s.connect();

let objectId;
s.post('Runtime.evaluate', { expression: 'a' }, (err, { result }) => {
  objectId = result.objectId;
});
s.post('Runtime.getProperties', { objectId }, (err, { internalProperties }) => {
  console.log(internalProperties);
});

дает

[
  {
    name: '[[FunctionLocation]]',
    value: {
      type: 'object',
      subtype: 'internal#location',
      value: [Object],
      description: 'Object'
    }
  },
  {
    name: '[[Scopes]]',
    value: {
      type: 'object',
      subtype: 'internal#scopeList',
      className: 'Array',
      description: 'Scopes[2]',
      objectId: '{"injectedScriptId":1,"id":24}'
    }
  }
]

с Node.js v12.3.1.

Ответ 2

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

К счастью, NodeJS проделал большую работу, выставив некоторые внутренние свойства v8 через модуль inspector.

Я написал небольшой модуль под названием func-loc который помогает получить расположение функции во время выполнения.

Пример:

const { locate } = require('func-loc');

const fn = () => {
  console.log('Hello there');
};

(async () => {
  const result = await locate(fn);
  console.log(result);
  // Will result: { source: 'file://__BASE_FOLDER__/func-loc/this-file.js', line: 3, column: 12 }
})();

Надеюсь, это поможет.

Ответ 3

console.log может отображать имя функции в Chrome с ограниченная поддержка языков.

Я нашел имя функции полезным при отладке обратных вызовов и при использовании шаблона наблюдателя. Обратите внимание, что для работы функций именования требуются функции имен (анонимные имена функций, очевидно, пусты).

function myFn() {}

if (typeof myFn === 'function') {
  console.log('Name of function', myFn.name)
}

Выходы Name of function myFn