Sono possibili operatori variabili?

C’è un modo per fare qualcosa di simile ad uno dei seguenti:

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

— O —

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

Non fuori dalla scatola. Tuttavia, è facile da build a mano in molte lingue, incluso JS.

 var operators = { '+': function(a, b) { return a + b }, '<': function(a, b) { return a < b }, // ... }; var op = '+'; alert(operators[op](10, 20)); 

È ansible utilizzare nomi basati su ascii come plus , per evitare di passare attraverso le stringhe se non è necessario. Tuttavia, la metà delle domande simili a questa è stata richiesta perché qualcuno aveva delle stringhe che rappresentano gli operatori e le funzioni ricercate da loro.

Puoi usare la eval() , ma non è una buona idea. Penso che il modo migliore sia scrivere le funzioni per i tuoi operatori in questo modo:

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

Credo che tu voglia un operatore variabile. eccone uno, creato come object. puoi cambiare l’operazione corrente cambiando:

 [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 

Da un’altra risposta che ho postato di recente, questo è in V8 e penso JavaScriptCore, ma non Firefox e non è spec. Poiché è ansible intercettare l’operazione e i comparatori, è ansible implementare l’overloading dell’operatore nella maggior parte delle situazioni con un po ‘di lavoro.

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

Produzione:

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

A questo punto hai tutti gli input e l’operazione in modo che la parte rimanente sia il risultato dell’operazione. Il ricevitore dell’operazione otterrà un valore primitivo, stringa o numero, e non è ansible impedirlo. Se non è un ricevitore arbitrario, ad esempio un’istanza della class che hai sovraccaricato l’operatore, puoi gestire varie trappole get / set per intercettare il valore in entrata / evitare la sovrascrittura. È ansible memorizzare gli operandi e le operazioni in una ricerca centralizzata e utilizzare un metodo semplice per risalire a un valore primitivo rispetto all’operazione che lo ha prodotto e quindi creare la logica desiderata per l’operazione personalizzata. Un altro metodo che consentirebbe ai ricevitori arbitrari che potrebbero essere ricostituiti in seguito in forms complesse sarebbe quello di codificare i dati nel valore primitivo in modo che possa essere reinserito nella class complessa. Come dire, un valore RGB di 3 distinti interi a 8 bit (255.255.255) potrebbe essere convertito in un singolo numero sul lato get e il ricevitore potrebbe essere banalmente convertito nei suoi componenti complessi. Oppure per dati più complessi è persino ansible restituire una stringa serializzata JSON.

Avere accesso a Harmony Proxies (Firefox6 +, Nodejs con flag) rende l’intero processo estremamente più facile, dato che puoi creare trapping proxy su praticamente tutto e introspettare l’intero processo da un capo all’altro e fare quello che vuoi. Le istanze di operando dei tuoi dati / class, il valoreOf / toString / getters di tutti i possibili valori che il motore interno può accedere, qualsiasi object ricevente che hai pre-consapevolezza e persino intrappolare ricevitori arbitrari nel caso di with(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; } with(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }

Non è ansible sovraccaricare gli operatori in JavaScript. Ovviamente è ansible utilizzare le funzioni per aiutare

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

possiamo implementarlo usando eval, dato che lo stiamo usando per il controllo dell’operatore.

 var number1 = 30; var number2 = 40; var operator = "==="; function evaluate(param1, param2, operator) { return eval(param1 + operator + param2); } if(evaluate(number1, number2, operator)) { } 

in questo modo possiamo usare la valutazione dynamic dell’operatore.