【问题标题】:Access function location programmatically以编程方式访问函数位置
【发布时间】:2017-04-30 00:08:30
【问题描述】:

是否可以在代码中访问 google chrome 开发者工具在使用控制台登录功能时显示的 ["[[FunctionLocation]]"] 属性?

【问题讨论】:

    标签: javascript google-chrome-devtools v8 console.log


    【解决方案1】:

    目前的答案是

    您在 Inspector 中看到的 [[FunctionLocation]] 属性已添加到调试器的 C++ 代码中的 V8Debugger::internalProperties() 中,该代码使用另一个 C++ 函数 V8Debugger::functionLocation() 来收集有关该函数的信息。然后functionLocation() 使用许多特定于 V8 的 C++ API,例如 v8::Function::GetScriptLineNumber() and GetScriptColumnNumber() 来找出确切的信息。

    上述所有 API 仅适用于 C++ 代码,而非 JavaScript 代码。换句话说,网页上的 JavaScript 代码无法直接访问这些信息。


    但是,您可以使用 Chrome 扩展程序访问这些属性。最近,Chrome 使用的 V8 JavaScript 引擎增加了对通过 Chrome DevTools Protocol 访问这些属性的支持。特别是,您可以通过Runtime.getProperties 调用获取内部属性。此外,它seems like Chrome 扩展可能能够通过chrome.debugger 与 DevTools 协议进行交互。

    在 Node.js 中使用 DevTools 协议的概念证明,该协议可以使用 Inspector 内置模块直接访问协议(Mohamed 在他们的回答中提到):

    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。

    【讨论】:

    • 这是真正的科学,感谢您深入研究并解释它,而不是猜测或巫术。
    • 蒂莫西你知道this question的答案吗?尝试在 Chrome 扩展而不是开发工具中访问 [[FunctionLocation]]
    • @mike-pz 我已经回答了这个问题,并用一些关于扩展的附加信息来扩充这个答案。
    【解决方案2】:

    console.log 可以在 Chrome 中以limited language support 显示函数名称。

    我发现函数名在调试回调和使用observer pattern 时很有用。请注意,这需要命名函数才能工作(匿名函数名称显然是空白的)。

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

    输出Name of function myFn

    【讨论】:

    • 我不会否决这个答案,因为它可能对其他人有用,但name 是标准 Function 对象定义的一部分,OP 正在寻找的是新的 Google Chrome Dev 的一部分工具功能,它还公开了定义此类功能的文件名[[FunctionName]]
    【解决方案3】:

    我知道这个问题发布已经有一段时间了。现在,我遇到了同样的问题。我需要在运行时访问函数位置。

    幸运的是,NodeJS 通过inspector 模块公开了一些 v8 内部属性,做得很好。

    我编写了一个名为 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 }
    })();
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-12-13
      • 1970-01-01
      • 2016-09-06
      • 2014-09-30
      • 2016-11-09
      • 1970-01-01
      • 2010-12-13
      • 2018-08-14
      • 2010-09-05
      相关资源
      最近更新 更多