Javascript: перегрузка оператора
Я работаю с JavaScript уже несколько дней и дошел до точки, где я хочу перегружать операторы для моих определенных объектов.
после того, как вы нашли это в google, кажется, вы не можете официально сделать это, но есть несколько человек, которые утверждают, что это какой-то длинный способ выполнения этого действия.
в основном я сделал класс Vector2 и хочу быть в состоянии сделать следующее:
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.
вместо этого я должен сделать это:
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.
есть ли подход, который я могу использовать для перегрузки операторов в моем классе Vector2? Как это просто выглядит просто некрасиво.
3 ответов:
как вы обнаружили, JavaScript не поддерживает перегрузку операторов. Самое близкое, что вы можете сделать, это реализовать
toString(который будет вызван, когда экземпляр должен быть принужден к тому, чтобы быть строкой) иvalueOf(который будет вызван, чтобы принудить его к ряду, например, при использовании+для добавления, или во многих случаях при использовании его для конкатенации, потому что+пытается сделать добавление перед конкатенацией), что довольно ограничено. Не позволяет создатьVector2объект как результат.
для людей, приходящих к этому вопросу, которые хотят строку или число в результате (вместо
Vector2), хотя, вот примерыvalueOfиtoString. Эти примеры не продемонстрировать перегрузку оператора, просто воспользовавшись встроенной обработкой JavaScript преобразования в примитивы:
valueOfэтот пример удваивает значение объекта
valсвойство в ответ на принуждение к a примитивно, например через+: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)или с ES2015 в
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)или просто с объектами, не конструкторы:
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в этом примере преобразуется значение объекта
valсвойство в верхнем регистре в ответ на принуждение к примитиву, например через+: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или с ES2015 в
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или просто с объектами, не конструкторы:
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
как сказал Ти Джей, вы не можете перегружать операторы в JavaScript. Однако вы можете воспользоваться
valueOfфункция для написания Хака, который выглядит лучше, чем с помощью таких функций, какaddкаждый раз, но накладывает ограничения на вектор, что x и y находятся между 0 и MAX_VALUE. Вот код: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); };тогда вы можете написать уравнения, как это:
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]
FYI бумаги.js решает эту проблему путем создания PaperScript, автономного, ограниченного javascript с перегрузкой операторов векторов, которые затем обрабатываются обратно в javascript.
но файлы paperscript должны быть специально определены и обработаны как таковые.
Comments