Da un'altra risposta che ho pubblicato di recente, questo è in V8 e penso JavaScriptCore, ma non Firefox e non è specifica. Dato che è possibile intercettare l'operazione e i comparatori, è possibile implementare il sovraccarico nativo 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 quindi la parte rimanente è il risultato dell'operazione. Il destinatario dell'operazione riceverà un valore primitivo, stringa o numero, e non puoi impedirlo. Se non è un ricevitore arbitrario, ad esempio un'istanza della classe che hai sovraccaricato dall'operatore, puoi gestire vari get / set trap per intercettare il valore in entrata / impedire la sovrascrittura. È possibile memorizzare gli operandi e l'operazione in una ricerca centrale e utilizzare un metodo semplice per ricondurre un valore primitivo all'operazione che lo ha prodotto, quindi creare la logica che si desidera per eseguire l'operazione personalizzata. Un altro metodo che consentirebbe ricevitori arbitrari che potrebbero essere successivamente ricostituiti in forme complesse sarebbe quello di codificare i dati nel valore primitivo in modo che possano essere invertiti nella tua classe complessa. Ad esempio, un valore RGB di 3 interi distinti a 8 bit (255,255,255) potrebbe essere convertito in un singolo numero all'estremità get e l'estremità del ricevitore potrebbe banalmente riconvertirlo nei suoi componenti complessi. Oppure, per dati più complessi, potresti persino restituire una stringa serializzata JSON.
Avere accesso a Harmony Proxies (Firefox6 +, Nodejs con flag) rende l'intero processo immensamente più semplice, poiché puoi creare proxy di trapping praticamente su tutto e analizzare l'intero processo dall'inizio alla fine e fare quello che vuoi. Le istanze dell'operando dei tuoi dati / classe, il valore di / toString / getter di ogni possibile valore a cui il motore interno può accedere, qualsiasi oggetto ricevitore di cui hai consapevolezza e persino intercettare ricevitori arbitrari nel caso diwith(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }