Javascript: operator overloading
As you've found, JavaScript doesn't support operator overloading. The closest you can come is to implement toString
(which will get called when the instance needs to be coerced to being a string) and valueOf
(which will get called to coerce it to a number, for instance when using +
for addition, or in many cases when using it for concatenation because +
tries to do addition before concatenation), which is pretty limited. Neither lets you create a Vector2
object as a result. Similarly, Proxy
(added in ES2015) lets you intercept various object operations (including property access), but again won't let you control the result of +=
on Vector
instances.
For people coming to this question who want a string or number as a result (instead of a Vector2
), though, here are examples of valueOf
and toString
. These examples do not demonstrate operator overloading, just taking advantage of JavaScript's built-in handling converting to primitives:
valueOf
This example doubles the value of an object's val
property in response to being coerced to a primitive, for instance via +
:
Or with ES2015's class
:
Or just with objects, no constructors:
toString
This example converts the value of an object's val
property to upper case in response to being coerced to a primitive, for instance via +
:
Or with ES2015's class
:
Or just with objects, no constructors:
As T.J. said, you cannot overload operators in JavaScript. However you can take advantage of the valueOf
function to write a hack which looks better than using functions like add
every time, but imposes the constraints on the vector that the x and y are between 0 and MAX_VALUE. Here is the 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);};
Then you can write equations like this:
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]
Actually, there is one variant of JavaScript that does support operator overloading. ExtendScript, the scripting language used by Adobe applications such as Photoshop and Illustrator, does have operator overloading. In it, you can write:
Vector2.prototype["+"] = function( b ){ return new Vector2( this.x + b.x, this.y + b.y );}var a = new Vector2(1,1);var b = new Vector2(2,2);var c = a + b;
This is described in more detail in the "Adobe Extendscript JavaScript tools guide" (current link here). The syntax was apparently based on a (now long abandoned) draft of the ECMAScript standard.