Javascript: operator overloading
Pracuję z JavaScript od kilku dni i doszedłem do punktu, w którym chcę przeciążać operatory dla zdefiniowanych obiektów.
Po pobycie w google szukając tego, wydaje się, że oficjalnie nie można tego zrobić, ale jest kilka osób, które twierdzą, że jakiś długi sposób wykonywania tej akcji.
W zasadzie zrobiłem klasę Vector2 i chcę być w stanie wykonać:
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.
Zamiast tego muszę to zrobić:
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.
Czy istnieje podejście mogę podjąć do przeciążenia operatorów w mojej klasie Vector2? Jak to wygląda po prostu brzydko.
3 answers
Jak już zauważyłeś, JavaScript nie obsługuje przeciążania operatorów. Najbliżej jest zaimplementować toString
(która zostanie wywołana, gdy instancja musi być zmuszona do bycia ciągiem znaków) i valueOf
(która zostanie wywołana, aby zmusić ją do liczby, na przykład podczas używania +
do dodawania, lub w wielu przypadkach, gdy używa jej do konkatenacji, ponieważ +
próbuje dodać przed konkatenacją), co jest dość ograniczone. Nie pozwala na tworzenie Vector2
obiektu jako wynik.
Dla osób, które przychodzą na to pytanie, które chcą ciąg lub liczbę jako wynik (zamiast Vector2
), Oto przykłady valueOf
i toString
. W przeciwieństwie do języka Java, JavaScript nie jest w stanie obsługiwać żadnych funkcji, które nie są w stanie obsługiwać żadnych funkcji.]}
valueOf
Ten przykład podwaja wartość właściwości val
obiektu w odpowiedzi na wymuszenie na prymitywie, na przykład poprzez +
:
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)
Lub z ES2015 ' s class
:
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)
Lub tylko z obiektami, bez konstruktorów:
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
W tym przykładzie wartość właściwości obiektu val
jest zamieniana na wielkie litery w odpowiedzi na wymuszenie na prymitywie, na przykład poprzez +
:
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
Lub z ES2015 ' s class
:
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
Lub tylko z obiektami, brak konstruktorów:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 22:02:51
Jak powiedział T. J., nie można przeciążać operatorów w JavaScript. Możesz jednak skorzystać z funkcji valueOf
, aby napisać hack, który wygląda lepiej niż używanie funkcji takich jak add
za każdym razem, ale nakłada ograniczenia na wektor, że x i y są między 0 a MAX_VALUE. Oto kod:
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);
};
Wtedy możesz pisać równania w ten sposób:
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]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-07 05:04:57
Dla twojej wiadomości.js rozwiązuje ten problem, tworząc PaperScript, samodzielny, scoped javascript z operatorem przeciążania wektorów, który następnie przetwarza z powrotem do javascript.
Ale pliki paperscript muszą być dokładnie określone i przetworzone jako takie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 21:34:46