Javascript: Operator Overloading

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 +:

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)

Is there operator overloading in ES6 / TypeScript? (or how to make object invokable)

There is no formal overloading of the () operator, but the ES5 technique works fine in modern JS as well.

As far as the Typescript story on this, your code works almost as is in Typescript 3.1

function interpolator(value: number) {
return value
}
interpolator.invert = function () { }
interpolator.setDomain = function (a : number, b: number) { }
interpolator.setRange = function (a: number, b: number) { }

// and the use like so
interpolator.setDomain(0, 1)
interpolator.setRange(50, 200)
let rangeValue = interpolator(0.5) // 125);

Playgrounk link

This is due to the new feature in 3.1 called Property assignments on function declarations.

Before 3.1 you need an extra namespace to achieve a properly typed function with extra members

function interpolator(value: number) {
return value
}
namespace interpolator {
export function invert() { }
export function setDomain(a: number, b: number) { }
export function setRange (a: number, b: number) { }
}

// and the use like so
interpolator.setDomain(0, 1)
interpolator.setRange(50, 200)
let rangeValue = interpolator(0.5) // 125);

Playgrounk link

How would you overload the [] operator in javascript

You can't overload operators in JavaScript.

It was proposed for ECMAScript 4 but rejected.

I don't think you'll see it anytime soon.

Overloading Arithmetic Operators in JavaScript?

As far as I'm aware, Javascript (at least as it exists now) doesn't support operator overloading.

The best I can suggest is a class method for making new quota objects from several others. Here's a quick example of what I mean:

// define an example "class"
var NumClass = function(value){
this.value = value;
}
NumClass.prototype.toInteger = function(){
return this.value;
}

// Add a static method that creates a new object from several others
NumClass.createFromObjects = function(){
var newValue = 0;
for (var i=0; i<arguments.length; i++){
newValue += arguments[i].toInteger();
}
return new this(newValue)
}

and use it like:

var n1 = new NumClass(1);
var n2 = new NumClass(2);
var n3 = new NumClass(3);

var combined = NumClass.createFromObjects(n1, n2, n3);

Can I overload JavaScript's indexing operator?

Operator overloading is not possible in javascript.

Check the answer given here https://stackoverflow.com/a/1711405/1903116

Does Typescript have Operator Overloading?

No it does not exist. It is very unlikely that it will exist unless there is a clear Spec on how it might be implemented in Pure JavaScript.

Can I define custom operator overloads in Javascript?

I agree that the equal function on the vector prototype is the best solution. Note that you can also build other infix-like operators via chaining.

function Vector(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}

Vector.prototype.add = function (v2) {
var v = new Vector(this.x + v2.x,
this.y + v2.y,
this.z + v2.z);
return v;
}

Vector.prototype.equal = function (v2) {
return this.x == v2.x && this.y == v2.y && this.z == v2.z;
}

You can see online sample here.

Update: Here's a more extensive sample of creating a Factory function that supports chaining.

Override the Equivalence Comparison in Javascript

That is because the == operator doesn't compare only primitives, therefore doesn't call the valueOf() function. Other operators you used do work with primitives only. I'm afraid you cannot achieve such thing in Javascript. See http://www.2ality.com/2011/12/fake-operator-overloading.html for some more details.



Related Topics



Leave a reply



Submit