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
Enabling Cross-Origin Resource Sharing on Iis7
How to Convert a Currency String to a Double with JavaScript
How to Turn JavaScript Array into Comma-Separated List
JavaScript Asynchronous Return Value/Assignment with Jquery
Can JavaScript Connect with MySQL
Axios Posting Params Not Read by $_Post
How to Open a New Window and Insert HTML into It Using Jquery
How to Load Images Dynamically (Or Lazily) When Users Scrolls Them into View
Run a Website in Fullscreen Mode
How to Auto-Submit an Upload Form When a File Is Selected
What Is the Minimum Valid JSON
What Does the Plus Sign Do in '+New Date'
JavaScript Removeeventlistener Not Working
How to Check If an HTML Element Is Empty Using Jquery
Jquery Ajax Call to PHP Script with JSON Return