代码之家  ›  专栏  ›  技术社区  ›  Dave

按名称模式搜索局部javascript变量

  •  2
  • Dave  · 技术社区  · 9 年前

    function foo() {
        const x = 2;
    
        self.x; // undefined
        this.x; // undefined
        window.x; // undefined
        x; // 2, obviously
        eval('x'); // 2
    }
    

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

    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 能够通过名称访问变量意味着该值在某处可用。有没有办法找到这个变量?或者我必须求助于重写(可能非常复杂)不在我直接控制之下的代码的技术吗?

    或者类似的黑客解决方案。已经在执行任意代码,因为执行用户提供的代码才是目的。

    3 回复  |  直到 9 年前
        1
  •  1
  •   Duncan Thacker    9 年前

    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/

        2
  •  0
  •   Duncan Thacker    9 年前

    在这里,一种可能帮助您的方法是在全局范围而不是在函数中求值,这可能会将函数放在窗口对象而不是局部范围中。

    最简单的方法可能是在文档中写入一个新标记,并注入用户提供的代码。

        3
  •  0
  •   Estus Flask    9 年前

    依赖变量名是错误的方法。

    eval 变量在精简代码中没有预期的名称 . 他们是 a b , c ...

    为了维护它们的名称,它们应该是对象属性,因此它们在对象上可用。

    这就是重构,这就是应该做的事情,以避免糟糕的代码发出臭味并产生重大问题。