Javascript: surcharge de l'opérateur
je travaille avec JavaScript depuis quelques jours maintenant et j'en suis arrivé à un point où je veux surcharger les opérateurs pour mes objets définis.
après un passage sur google à la recherche de cela, il semble que vous ne pouvez pas officiellement le faire, mais il y a quelques personnes là-bas qui revendiquent une façon à long terme d'effectuer cette action.
en gros, j'ai fait une classe Vector2 et je veux pouvoir faire ce qui suit:
var x = new Vector2(10,10);
var y = new Vector2(10,10);
x += y; //This does not result in x being a vector with 20,20 as its x & y values.
à la place, je dois faire ceci:
var x = new Vector2(10,10);
var y = new Vector2(10,10);
x = x.add(y); //This results in x being a vector with 20,20 as its x & y values.
y a-t-il une approche que je peux adopter pour surcharger les opérateurs de ma classe Vector2? Comme cela semble juste laid.
3 réponses
comme vous l'avez constaté, JavaScript ne supporte pas la surcharge de l'opérateur. Le plus proche que vous pouvez venir est d'implémenter toString
(qui sera appelé quand l'instance doit être forcée à être une chaîne de caractères) et valueOf
(qui sera appelé pour la forcer à un nombre, par exemple en utilisant +
pour addition, ou dans de nombreux cas en l'utilisant pour concaténation parce que +
essaie de faire addition avant concaténation), ce qui est assez limité. Ni vous permet de créer un Vector2
objet.
pour les personnes venant à cette question qui veulent une chaîne ou un nombre comme résultat (au lieu d'un Vector2
), cependant, voici des exemples de valueOf
et toString
. Ces exemples ne démontrent pas la surcharge de l'opérateur, juste en profitant de JavaScript intégré à la conversion de conversion en primitives:
valueOf
cet exemple double la valeur de la propriété val
d'un objet en réponse à une contrainte exercée sur une primitive, par exemple via +
:
function Thing(val) {
this.val = val;
}
Thing.prototype.valueOf = function() {
// Here I'm just doubling it; you'd actually do your longAdd thing
return this.val * 2;
};
var a = new Thing(1);
var b = new Thing(2);
console.log(a + b); // 6 (1 * 2 + 2 * 2)
ou avec class
de ES2015:
class Thing {
constructor(val) {
this.val = val;
}
valueOf() {
return this.val * 2;
}
}
const a = new Thing(1);
const b = new Thing(2);
console.log(a + b); // 6 (1 * 2 + 2 * 2)
ou juste avec des objets, aucun constructeur:
var thingPrototype = {
valueOf: function() {
return this.val * 2;
}
};
var a = Object.create(thingPrototype);
a.val = 1;
var b = Object.create(thingPrototype);
b.val = 2;
console.log(a + b); // 6 (1 * 2 + 2 * 2)
toString
cet exemple convertit la valeur de la propriété val
d'un objet en majuscule en réponse à une contrainte exercée sur une primitive, par exemple via +
:
function Thing(val) {
this.val = val;
}
Thing.prototype.toString = function() {
return this.val.toUpperCase();
};
var a = new Thing("a");
var b = new Thing("b");
console.log(a + b); // AB
ou avec class
de ES2015:
class Thing {
constructor(val) {
this.val = val;
}
toString() {
return this.val.toUpperCase();
}
}
const a = new Thing("a");
const b = new Thing("b");
console.log(a + b); // AB
ou juste avec des objets, aucun constructeur:
var thingPrototype = {
toString: function() {
return this.val.toUpperCase();
}
};
var a = Object.create(thingPrototype);
a.val = "a";
var b = Object.create(thingPrototype);
b.val = "b";
console.log(a + b); // AB
comme L'a dit T. J., vous ne pouvez pas surcharger les opérateurs en JavaScript. Toutefois, vous pouvez profiter de la fonction valueOf
pour écrire un hack qui semble meilleur que l'utilisation de fonctions comme add
à chaque fois, mais impose les contraintes sur le vecteur que les x et y sont entre 0 et MAX_VALUE. Voici le code:
var MAX_VALUE = 1000000;
var Vector = function(a, b) {
var self = this;
//initialize the vector based on parameters
if (typeof(b) == "undefined") {
//if the b value is not passed in, assume a is the hash of a vector
self.y = a % MAX_VALUE;
self.x = (a - self.y) / MAX_VALUE;
} else {
//if b value is passed in, assume the x and the y coordinates are the constructors
self.x = a;
self.y = b;
}
//return a hash of the vector
this.valueOf = function() {
return self.x * MAX_VALUE + self.y;
};
};
var V = function(a, b) {
return new Vector(a, b);
};
alors vous pouvez écrire des équations comme ceci:
var a = V(1, 2); //a -> [1, 2]
var b = V(2, 4); //b -> [2, 4]
var c = V((2 * a + b) / 2); //c -> [2, 4]
pour information.js résout ce problème en créant PaperScript, un javascript autonome, scopé avec la surcharge par l'opérateur des vecteurs, qu'il traite ensuite de nouveau dans javascript.
mais les fichiers paperscript doivent être spécifiquement spécifiés et traités comme tels.