变量运算符可能吗?

| 有没有一种方法可以执行以下任一操作:
var1 = 10; var2 = 20;
var operator = \"<\";
console.log(var1 operator var2); // returns true
- 要么 -
var1 = 10; var2 = 20;
var operator = \"+\";
total = var1 operator var2; // total === 30
    
已邀请:
并非开箱即用。但是,很容易以多种语言(包括JS)进行手工构建。
var operators = {
    \'+\': function(a, b) { return a + b },
    \'<\': function(a, b) { return a < b },
     // ...
};

var op = \'+\';
alert(operators[op](10, 20));
您可以使用诸如ѭ3之类的基于ascii的名称,以避免在不需要时使用字符串。但是,有人问了与此类似的问题的一半,因为有人用字符串表示运算符并希望从中获取功能。     
我相信您想要一个变量运算符。这是作为对象创建的。您可以通过更改以下内容来更改当前操作:
[yourObjectName].operation = \"<\" //changes operation to less than


function VarOperator(op) { //you object containing your operator
    this.operation = op;

    this.evaluate = function evaluate(param1, param2) {
        switch(this.operation) {
            case \"+\":
                return param1 + param2;
            case \"-\":
                return param1 - param2;
            case \"*\":
                return param1 * param2;
            case \"/\":
                return param1 / param2;
            case \"<\":
                return param1 < param2;
            case \">\":
                return param1 > param2;
        }
    }
}

//sample usage:
var vo = new VarOperator(\"+\"); //initial operation: addition
vo.evaluate(21,5); // returns 26
vo.operation = \"-\" // new operation: subtraction
vo.evaluate(21,5); //returns 16
vo.operation = \">\" //new operation: \">\"
vo.evaluate(21,5); //returns true
    
您可以使用
eval()
函数,但这不是一个好主意。 我认为更好的方法是像这样为您的操作员编写函数:
var addition = function(first, second) {
   return first+second;
};

var subtraction = function(first, second) {
   return first-second;
};

var operator = addition;

alert(operator(12, 13));

var operator = subtraction;

alert(operator(12, 13));
    
我们可以使用eval来实现此功能,因为我们将其用于操作员检查。
var number1 = 30;
var number2 = 40;
var operator = \"===\";

function evaluate(param1, param2, operator) {
     return eval(param1 + operator + param2);
}

if(evaluate(number1, number2, operator)) {
}
这样,我们可以使用动态运算符评估。     
我最近发布的另一个答案是,这是在V8中,我认为是JavaScriptCore,但不是Firefox,这不是规范。由于您可以捕获操作和比较器,因此您可以在大多数情况下通过一些工作来实现操作员本机重载。
var actions = [];
var overload = {
  valueOf: function(){
    var caller = arguments.callee.caller;
    actions.push({
      operation: caller.name,
      left: caller.arguments[0] === this ? \"unknown\" : this,
      right: caller.arguments[0]
    });
    return Object.prototype.toString.call(this);
  }
};
overload.toString = overload.valueOf;
overload == 10;
overload === 10;
overload * 10;
10 / overload;
overload in window;
-overload;
+overload;
overload < 5;
overload > 5;
[][overload];
overload == overload;
console.log(actions);
输出:
[ { operation: \'EQUALS\',
    left: overload,
    right: 10 },
  { operation: \'MUL\',
    left: overload,
    right: 10 },
  { operation: \'DIV\',
    left: \'unknown\',
    right: overload },
  { operation: \'IN\',
    left: overload,
    right: DOMWindow },
  { operation: \'UNARY_MINUS\',
    left: overload,
    right: undefined },
  { operation: \'TO_NUMBER\',
    left: overload,
    right: undefined },
  { operation: \'COMPARE\',
    left: overload,
    right: 5 },
  { operation: \'COMPARE\',
    left: \'unknown\',
    right: overload },
  { operation: \'ToString\',
    left: \'unknown\',
    right: overload } ]
此时,您将拥有所有输入和操作,因此其余部分是操作的结果。该操作的接收者将获得一个原始值,可以是字符串或数字,您不能阻止这种情况。如果它不是一个任意接收者,比如说您的运算符已重载该类的实例,则可以处理各种get / set陷阱来拦截传入的值/防止覆盖。您可以将操作数和操作存储在某个中央查询中,并使用一种简单的方法将原始值追溯到产生该值的操作,然后创建要进行自定义操作的任何逻辑。另一种允许任意接收者随后可以重构为复杂形式的方法是将数据编码为原始值,以便可以将其反向转换为复杂类。就像说,可以将3个不同的8位整数(255,255,255)的RGB值在get端转换为单个数字,而接收器端可以将其转换回复杂的分量。或者,对于更复杂的数据,您甚至可以返回JSON序列化的字符串。 可以访问Harmony Proxies(Firefox6 +,带标志的Nodejs)使整个过程变得非常容易,因为您可以在几乎所有内容上创建陷阱代理,并从头到尾进行整个过程的内省,并做您想做的任何事情。您的数据/类的操作数实例,内部引擎可以访问的每个可能值的valueOf / toString / getters,任何您事先知道的接收器对象,甚至在情况为ѭ10时都捕获任意接收器     
您不能在JavaScript中重载运算符。您可以偏离路线使用功能来帮助
var plus = function(a, b) {
    return a + b;
};

var smaller = function(a, b) { 
    return a < b;
};

var operator = plus;
var total = operator(a, b);
operator = smaller;
if(operator(var1, var2)){ /*do something*/ }
    

要回复问题请先登录注册