5

ho questa classe razionale che ha un metodo per ogni operazione (aggiungere, mult ecc)Attiva una classe razionale per gestire operatori matematici

function Rational(nominator, denominator){ 
    this.nominator = nominator; 
    this.denominator = denominator || 1;  
} 

Rational.prototype = { 
    mult: function(that) { 
     return new Rational(
      this.nominator * that.nominator, 
      this.denominator * that.denominator 
      ); 
    }, 
    print: function() { 
     return this.nominator + '/' + this.denominator; 
    } 
}; 

var a = new Rational(1,2), 
    b = new Rational(3); 

console.log(a.mult(b).print()); // 3/2 

Posso renderlo più "naturale" per esempio abilitare console.log(a * b)?

+4

JavaScript non supporta l'overloading degli operatori. Puoi però sostituire 'print()' con 'toString'. – georg

+0

Potrebbe funzionare una qualche forma di sostituzione di eval e stringa, come ad esempio: console.log (Funzione ("a * b" .replace ("* b", ". Mult (b) .print()"))) Là sono [uno] (http://stackoverflow.com/a/1390694/1113772) o [due] (http://stackoverflow.com/questions/14147290/how-can-i-set-loop-imacros-by- javascript) domande su macro che potrebbero essere d'aiuto. –

risposta

9

Non è possibile sovraccaricare gli operatori (leggi similar questions).

Inoltre, un metodo dedicato come mult può essere trattata come un segno di buon design (e non solo in Javascript), dal momento che cambiando l'originale comportamento operatore può confondere gli utenti (o meglio, un numero razionale in realtà un buon candidato per sovraccarico).

È possibile modificare print-toString come utente thg435 ha suggerito.

Andando ancora oltre:

Rational.prototype = { 
    mult : ... , 
    toString: ... , 
    valueOf: function() { return this.nominator/this.denominator; } 
}; 

Ciò consentirà al a * b sintassi (nota: non si controlla il Rationals più, ma piuttosto su primitive).

+0

Questo è quello che ho pensato anch'io, tuttavia si è rivelato sbagliato: prova 'new Rational (1,3) .toString()'. – georg

+0

@ thg435 funziona perfettamente nel motore di Firefox – emesx

+0

No, non lo è. Se si definisce valueOf, la conversione stringa lo utilizzerà e non il toString. Quindi ottieni '0.3333' invece di' 1/3'. – georg

0

Come idea, si può provare a scrivere un parser se stessi in modo che si scrive qualche cosa come questa:

console.log(R("a * b")); 

Dove R è la funzione che converte un * b per a.mult (b) e poi questo è eval.

3

Il più vicino si può ottenere è una sorta di operatore di aliasing, come questa:

/* Accepts a symbolic or string operator, returns a function which accepts numbers */ 
function operator(node) 
    { 
    //Mapping between string and symbol operators 
    var map = {"mod": "%", "mult": "*", "div": "/", "plus": "+", "minus": "-"} 

    //Return a function which applies the string or symbol operator to two numbers 
    return Function("x,y", "return x" + (map[node] || node) + "y"); 
    } 

// pass "*" to operator; pass 5,7 to returned function 
var foo = operator("*")(5,7); 

// pass "plus" to operator; pass 3,2 to returned function 
var bar = operator("plus")(3,2); 

// pass "mod" to operator; pass 1,0 to returned function 
var baz = operator("mod")(1,0); 

console.log(["foo",foo,"bar",bar,"baz",baz]); //["foo", 35, "bar", 5, "baz", NaN] 

Riferimenti