需要在eval中使undefined == true的Hack

时间:2015-12-07 11:01:41

标签: javascript eval

我有一个允许根据环境评估字符串的函数

function filt(M, filterString, cb){
    var res
    try{
        res = eval(filterString)
    } catch(me){
        // If in doubt permit               
        res = true
    }
    cb(res)
}

问题是我希望这个过滤器是乐观的。您可以在catch中看到乐观情绪,如果出现任何问题,则将响应设置为true。

如果我运行filt({ age : 20 }, 'M.age < 21', callback),那么我的回调会返回true。同样,filt({ age: 21}, 'M.age < 21', callback)会按预期返回false。

但是我还希望以下内容也返回true: filt({}, 'M.age < 21', callback)。但是undefined==true为false(类似于所有带undefined的布尔表达式)。我考虑过使用正则表达式检查字符串(我的所有变量都作为对象M上的字段传递)。因此,如果filterString包含M.varname(或M."varname"M["varname"],则如果M上没有此类字段,则替换为true。但在编码之前我以为我会把触角伸出来看看是否有更好的方法。

有什么想法吗?提前谢谢。

更新

感谢您的反馈,我可以看到我的整个方法需要重新思考。为了简化,我想知道是否有一种方法来评估具有未知值的表达式,以便如果表达式涉及并且未知,则结果是未知的。例如,在伪代码中:

M > 21 = unknown if M == unknown
M > 21 = true if M == 23
M > 21 = false if M == 'fish'
M > 21 | true = true independent of the value of M.

1 个答案:

答案 0 :(得分:0)

部分解决方案:不回答问题

我在这里发布一个过于乐观的部分解决方案。这包括我的单元测试,但它是可怕的,可能是危险的。在考虑做这样的事情之前,请阅读上面其他用户的评论。

function(M, filterString, cb){

    var regexp = /M(\."\w+"|\.'\w+'|\.\w+|\["\w+"\]|\['\w+'\])+/g
    /*
        Matches all of the following 
        M."a"
        M.'a'
        M.a["b"].c
        M["a"].b['c']
        M.a.b
    */

    var expectedVariables = filterString.match(regexp)

    // Check that the variables in the filterString are available
    var allMetaDataAvailable = true
    for(var i=0 ; i< expectedVariables.length; i++){
        if (typeof eval(expectedVariables[i]) =='undefined'){
            allMetaDataAvailable = false
        }
    }

    if (!allMetaDataAvailable){
         // Optimistic
         cb(true)
    } else {
         // Evalue the expression
         var res
         try{
              res = eval(filterString)
         } catch(me){
              // something went wrong - allow.
              res = true
         }
         cb(res)

     }
}

这只是一个部分解决方案的原因是字符串表达式M.age < 20 | M.gender=='f'将在M = { gender : 'm' }时返回true,因为它不知道age的值然后它乐观地说表达式可能(将来 - 一旦定义了值)变为真 - 在这种情况下显然是不可能的,因为我们已经知道gender的值是错误的。

更新:我现在发现了一个名为JSEP.js的非常轻量级的库,用于创建javascript表达式的抽象语法树。这似乎是实现基于javascript的三元逻辑的理想起点,能够正确处理布尔表达式中的未知值。