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)
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.
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
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
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 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.
Function overloading in Javascript - Best practices
The best way to do function overloading with parameters is not to check the argument length or the types; checking the types will just make your code slow and you have the fun of Arrays, nulls, Objects, etc.
What most developers do is tack on an object as the last argument to their methods. This object can hold anything.
function foo(a, b, opts) {
// ...
if (opts['test']) { } //if test param exists, do something..
}
foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals", "bar":"tree"});
Then you can handle it anyway you want in your method. [Switch, if-else, etc.]
Related Topics
Syntaxerror: Unexpected Token Function - Async Await Nodejs
Programmatically Select Text in a Contenteditable HTML Element
How to Listen for Keyboard Open/Close in JavaScript/Sencha
Are There JavaScript or Ruby Versions of "HTML Tidy"
Setting a Variable to Get Return from Call Back Function Using Promise
Access Elements of Parent Window from Iframe
Adding/Removing Items from a JavaScript Object with Jquery
Combined Comparison/"Spaceship" Operator (<=>) in JavaScript
Jquery UI - Close Dialog When Clicked Outside
Using Enter Key with Action Button in R Shiny
What's the Difference Between Console.Dir and Console.Log
Reactjs - Lifting State Up VS Keeping a Local State
How Should Look a Application.Scss File in Ruby
JavaScript in Wkwebview - Evaluatejavascript VS Adduserscript
JavaScript Parse Float Is Ignoring the Decimals After My Comma