Değişken Operatörler Mümkün mü?


90

Aşağıdakilerden herhangi birine benzer bir şey yapmanın bir yolu var mı:

var1 = 10; var2 = 20;
var operator = "<";
console.log(var1 operator var2); // returns true

- VEYA -

var1 = 10; var2 = 20;
var operator = "+";
total = var1 operator var2; // total === 30

Yanıtlar:


177

Kutunun dışında değil. Ancak, JS dahil birçok dilde elle oluşturmak kolaydır.

var operators = {
    '+': function(a, b) { return a + b },
    '<': function(a, b) { return a < b },
     // ...
};

var op = '+';
alert(operators[op](10, 20));

Gerekmiyorsa plusdizelerden geçmekten kaçınmak için ascii tabanlı isimler kullanabilirsiniz. Bununla birlikte, buna benzer soruların yarısı soruldu çünkü birisinin operatörleri temsil eden dizeleri vardı ve onlardan işlevler istiyordu.


6

Değişken bir operatör istediğinize inanıyorum. İşte nesne olarak oluşturulmuş bir tane. mevcut işlemi değiştirerek değiştirebilirsiniz:

[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

6

eval()Fonksiyonu kullanabilirsiniz , ancak bu iyi bir fikir değil. Sanırım daha iyi bir yol, operatörleriniz için aşağıdaki gibi fonksiyonlar yazmaktır:

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

6

bunu operatör kontrolü için kullandığımız için eval kullanarak uygulayabiliriz.

var number1 = 30;
var number2 = 40;
var operator = "===";

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

if(evaluate(number1, number2, operator)) {
}

bu şekilde dinamik operatör değerlendirmesini kullanabiliriz.


3

Yakın zamanda gönderdiğim başka bir cevaptan, bu V8'de ve JavaScriptCore olduğunu düşünüyorum, ancak Firefox değil ve spesifik değil. İşlemi ve karşılaştırıcıları yakalayabileceğiniz için, çoğu durumda biraz çalışmayla operatör yerel aşırı yüklemesi uygulayabilirsiniz.

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

Çıktı:

[ { 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 } ]

Bu noktada tüm girdilere ve işlemlere sahip olursunuz, böylece kalan kısım işlemin sonucudur. İşlemin alıcısı dize veya sayı gibi ilkel bir değer alır ve bunu önleyemezsiniz. Bu rastgele bir alıcı değilse, örneğin operatörünüzün aşırı yüklediği sınıfın bir örneğini söyleyin, gelen değeri durdurmak / üzerine yazmayı önlemek için çeşitli get / set tuzaklarını işleyebilirsiniz. İşlenenleri ve işlemi bazı merkezi aramalarda saklayabilir ve basit bir yöntemi, onu üreten işleme geri döndürmek için basit bir yöntem kullanabilir ve ardından özel işleminizi yapmak istediğiniz mantığı oluşturabilirsiniz. Daha sonra karmaşık biçimlere dönüştürülebilecek rastgele alıcılara izin veren başka bir yöntem, verileri karmaşık sınıfınıza geri döndürülebilmesi için ilkel değere kodlamaktır. Diyelim ki 3 farklı 8 bitlik tamsayıdan oluşan bir RGB değeri (255,255,255), başlangıçta tek bir sayıya dönüştürülebilir ve alıcı uç onu karmaşık bileşenlerine geri dönüştürebilir. Veya daha karmaşık veriler için, JSON serileştirilmiş bir dizge bile döndürebilirsiniz.

Harmony Proxy'lerine (Firefox6 +, Nodejs with flag) erişime sahip olmak, tüm bu süreci son derece kolaylaştırır, çünkü temelde her şey için yakalama proxy'leri oluşturabilir ve tüm süreci uçtan uca iç gözlem yapabilir ve istediğinizi yapabilirsiniz. Verilerinizin / sınıfınızın işlenen örnekleri, dahili motorun erişebileceği her olası değerin değeri / toString / alıcıları, önceden farkında olduğunuz herhangi bir alıcı nesnesi ve hatta rastgele alıcıları tuzağa düşürme durumundawith(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }


2

JavaScript'te operatörleri aşırı yükleyemezsiniz. Elbette yardımcı olmak için işlevleri kullanabilirsiniz

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*/ }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.