D'après une autre réponse que j'ai récemment publiée, c'est dans V8 et je pense que JavaScriptCore, mais pas Firefox et ce n'est pas des spécifications. Comme vous pouvez intercepter l'opération et les comparateurs, vous pouvez implémenter une surcharge native de l'opérateur dans la plupart des situations avec un peu de travail.
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);
Production:
[ { 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 } ]
À ce stade, vous avez toutes les entrées et l'opération, donc la partie restante est le résultat de l'opération. Le récepteur de l'opération obtiendra une valeur primitive, soit une chaîne, soit un nombre, et vous ne pouvez pas empêcher cela. Si ce n'est pas un récepteur arbitraire, disons une instance de la classe que vous avez surchargée par l'opérateur, vous pouvez gérer diverses interruptions get / set pour intercepter la valeur entrante / empêcher l'écrasement. Vous pouvez stocker les opérandes et l'opération dans une recherche centrale et utiliser une méthode simple pour retracer une valeur primitive jusqu'à l'opération qui l'a produite, puis créer la logique de votre choix pour votre opération personnalisée. Une autre méthode qui autoriserait des récepteurs arbitraires qui pourraient plus tard être reconstitués sous des formes complexes consisterait à coder les données dans la valeur primitive afin qu'elles puissent être inversées dans votre classe complexe. Comme disons, une valeur RVB de 3 entiers 8 bits distincts (255, 255, 255) pourrait être convertie en un seul nombre à la fin et le récepteur pourrait la reconvertir en ses composants complexes. Ou pour des données plus complexes, vous pouvez même renvoyer une chaîne sérialisée JSON.
Avoir accès à Harmony Proxies (Firefox6 +, Nodejs avec indicateur) facilite énormément tout ce processus, car vous pouvez créer des proxies de piégeage sur pratiquement tout et introspecter l'ensemble du processus de bout en bout et faire ce que vous voulez. Les instances d'opérande de vos données / classe, les valueOf / toString / getters de toutes les valeurs possibles auxquelles le moteur interne peut accéder, tout objet récepteur dont vous avez une pré-connaissance, et même intercepter des récepteurs arbitraires dans le cas dewith(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }