javascript - 按名称模式搜索本地 javascript 变量

标签 javascript scope ecmascript-6

在 Javascript 中,局部变量不存在于我所知道的任何对象上。也就是说,

function foo() {
    const x = 2;

    self.x; // undefined
    this.x; // undefined
    window.x; // undefined
    x; // 2, obviously
    eval('x'); // 2
}

最后一个选项 eval('x') 表明可以通过名称引用这些变量。我希望扩展它并使用名称 pattern 访问变量:

function foo() {
    // Code not under my direct control
    function foobar_abc() {}
    function other_functions() {}

    // Code under my control
    const matchingFunction = // find the function with name matching 'foobar_*'
}

如果它存在于一个对象上,我会使用像 myObject[Object.keys(myObject).find((key) => key.startsWith('foobar_'))] 这样的东西。如果它在全局范围内,myObject 将是 window 并且一切正常。

eval 能够通过名称访问变量的事实意味着该值在某处可用。有什么办法可以找到这个变量吗?还是我必须求助于重写不受我直接控制的(可能非常复杂的)代码的技术?

我的目标是现代浏览器,在这个用例中我不介意使用 eval 或类似的 hacky 解决方案。任意代码已经在执行,因为执行用户提供的代码是目的。

最佳答案

另一种选择是使用代码解析来使用 JavaScript AST(抽象语法树)库推断函数名称。 “esprima”包可能是个不错的地方:

https://www.npmjs.com/package/esprima

所以你可以这样做

import esprima from 'esprima'

const userCodeStructure = esprima.parseScript( userProvidedJavascriptString );

const allTopLevelFunctionDeclarations = userCodeStructure.body.filter( declaration => declaration.type === "FunctionDeclaration" );

const allTopLevelFunctionNames = allTopLevelFunctionDeclarations.map( d => d.id );

我自己没有尝试过,文档表明它应该可以工作(或类似的东西):

http://esprima.readthedocs.io/en/latest/

关于javascript - 按名称模式搜索本地 javascript 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46207328/

相关文章:

javascript - 使用循环添加标签字段(ExtJs 2.3.0)

javascript - 更改输入元素父元素的样式

javascript - vue.js中如何向组件发送数据?

PHP 5 将类对象作为参数传递,它总是指针、副本或克隆吗?

javascript - 将 _without 和 _findWhere 从下划线转换为 ES6

javascript - 纳肖恩JS : execute AST string?

scope - 如何在 Gradle 构建中使用为 jar 文件提供的范围?

scope - java代码mule中访问流变量

javascript - 在类基组件中传递变量

javascript - 一种缩小或丑化 ES6 模板字符串的方法