program story

변수 연산자가 가능합니까?

inputbox 2020. 10. 16. 07:24
반응형

변수 연산자가 가능합니까?


다음 중 하나와 유사한 작업을 수행 할 수있는 방법이 있습니까?

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));

plus필요하지 않은 경우 문자열을 거치지 않도록, 와 같은 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 } ]

At this point you have all the inputs and the operation so the remaining part is the result of the operation. The receiver of the operation will get a primitive value, either string or number, and you can't prevent this. If it's not an arbitrary reciever, say an instance of the class you've operator overloaded, you can handle various get/set traps to intercept the incoming value/prevent overwriting. You can store the operands and operation in some central lookup and use a simple method to trace a primitive value back to the operation which produced it, and then create whatever logic you want to do your custom operation. Another method which would allow arbitrary receivers which could later be reconstituted into complex forms would be in encoding the data into the primitive value so that it can be reversed back into your complex class. Like say an RGB value of 3 distinct 8bit integers (255,255,255) could be be converted into a single number on the get end and the receiver end could trivial convert it back into its complex components. Or for more complex data you could even return a JSON serialized string.

Having access to Harmony Proxies (Firefox6+, Nodejs with flag) makes this whole process immensely easier, as you can create trapping proxies on basically everything and introspect the entire process from end to end and do whatever you want. The operand instances of your data/class, the valueOf/toString/getters of every possible value the internal engine may access, any receiver object you have pre-awareness of, and even trap arbitrary receivers in the case of with(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }


You can't overload operators in JavaScript. You can off course use functions to help

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*/ }

참고URL : https://stackoverflow.com/questions/5834318/are-variable-operators-possible

반응형