【问题标题】:JavaScript -- pass a boolean (or bitwise) operator as an argument?JavaScript - 将布尔(或按位)运算符作为参数传递?
【发布时间】:2019-04-29 02:52:34
【问题描述】:

在 C# 中有多种方法可以做到这一点C# Pass bitwise operator as parameter 特别是“Bitwise.Operator.OR”对象,但是这样的事情可以在 JavaScript 中完成吗?例如:

function check(num1, num2, op) {
    return num1 op num2; //just an example of what the output should be like
}

check(1,2, >); //obviously this is a syntax error, but is there some kind of other object or bitwise operator of some kind I can plug into the place of ">" and change the source function somehow?

【问题讨论】:

  • 不,没有办法。唯一的方法是传递一个包含运算符的字符串并使用 eval() 这不好。
  • @MaheerAli new Function 在这里更好。
  • @Kaiido 这将如何运作?
  • @Kaiido new Function 也使用eval()
  • 所有位运算符都希望接受两个或仅一个参数。如果您有多个运算符,则(使用对象示例)多次引用该对象,check['&&'](check['<'](2, 5), check['<'](8, 10)) 等,类似

标签: javascript bitwise-operators boolean-operations


【解决方案1】:

您可以创建一个对象,其中键作为运算符,值作为函数。您将需要括号符号来访问这些功能。

&&,|| 的两个以上参数可以使用 Rest 参数和 some()every()

对于按位运算符或+,-,*,/ 多个值,您可以使用reduce()

const check = {
  '>':(n1,n2) => n1 > n2,
  '<':(n1,n2) => n1 < n2,
  '&&':(...n) => n.every(Boolean),
  '||':(...n) => n.some(Boolean),
  '&':(...n) => n.slice(1).reduce((ac,a) => ac & a,n[0])
}

console.log(check['>'](4,6)) //false
console.log(check['<'](4,6)) /true
console.log(check['&&'](2 < 5, 8 < 10, 9 > 2)) //true

console.log(check['&'](5,6,7)  === (5 & 6 & 7))

【讨论】:

  • 如果有超过 2 个数字怎么办
  • @bluejayke 大于或小于运算符中怎么可能有两个以上的数字?
  • @bluejayke &gt;&lt; 的操作数不能超过两个。如果您想为||&amp;&amp; 提供更多信息,请查看编辑后的答案。
  • 好吧,我想这就是答案,你还能解释为什么“布尔”被传递给 n.every 吗?以及如何对位运算符执行此操作,或者特别是“&”运算符,例如,即使它为假,它也会继续到下一个表达式?
  • @bluejayke every 方法需要回调。所以我将Boolean 传递给它。它将检查所有(在第一种情况下)或至少(在第二种情况下)是否为真。 n.every(Boolean)n.every(x =&gt; x) 相同
【解决方案2】:

您可以执行链接答案所建议的完全相同的事情:

function check(num1, num2, op) {
  return op(num1, num2);
}

// Use it like this
check(3, 7, (x, y) => x > y);

您还可以创建一个提供所有这些操作的对象:

const Operators = {
  LOGICAL: {
    AND: (x, y) => x && y,
    OR: (x, y) => x || y,
    GT: (x, y) => x > y,
    // ... etc. ...
  },
  BITWISE: {
    AND: (x, y) => x & y,
    OR: (x, y) => x | y,
    XOR: (x, y) => x ^ y,
    // ... etc. ...
  }
};

// Use it like this
check(3, 5, Operators.BITWISE.AND);

【讨论】:

  • 如果每个操作符有两个以上的变量,比如 true && false && true && false 等等.....
  • 这似乎与 C# 函数不同:Bitwise.Operation(1, 2, Bitwise.Operator.OR); // 3、貌似“Bitwise.Operator.OR”是常量,不是函数
  • 幸运的是,嵌套在这里帮助了我们:BITWISE.AND(3, BITWISE.AND(7, BITWISE.AND(12, 93)))3 &amp; 7 &amp; 12 &amp; 93 相同:-D
  • stackoverflow.com/a/36107908/135978 - 在here 的示例中,它绝对是静态方法,而不是常量。
  • 好点,那么它只是递归跟踪它的问题
【解决方案3】:

怎么样:

 function binaryOperation( obj1, obj2, operation ) {
     return operation( obj1, obj2 );
 }
 function greaterThan( obj1, obj2 ) {
    return obj1 > obj2 ;
 }
 function lessThan( obj1, obj2 ) {
    return obj1 < obj2 ;
 }
 alert( binaryOperation( 10, 20, greaterThan ) );
 alert( binaryOperation( 10, 20, lessThan ) );

【讨论】:

    【解决方案4】:

    这是不可能的。但解决此问题的一种方法是执行以下操作:

    function evaluate(v1, v2, op) {
        let res = "" + v1 + op + v2;
        return eval(res)
    }
    console.log(evaluate(1, 2, "+"));
    # outputs 3
    

    但在传递 args 时要小心,因为它们会被评估,如果将一些 hacky 代码传递给函数,这是很危险的。

    【讨论】:

    • 好吧,如果您使用 eval,您不能只评估整个布尔值吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 2018-03-27
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 2013-06-23
    相关资源
    最近更新 更多