Python Magic Methods in JavaScript

125 Views Asked by At

I'm a new JavaScript coder trying to figure out classes.

I was wondering if there is something in JavaScript that has similar functionality to Python's __str__ or __add__, or anything of the sort, magic methods so I can run a function when two classes are, say, added together.

1

There are 1 best solutions below

0
Mike Stay On

TLDR: you can't overload operators, but there are some hacks that will get you something similar.

Doing it the right way

There are various preprocessors that will rewrite overloaded operators to method calls, but that's a deploy-time solution rather than a runtime solution.

There is a TC-39 proposal to add operator overloading to the language, but it's not a language feature yet.

Hacks

The relevant part of the spec for addition is here. The upshot is that when you treat an object as a number or a string, the valueOf and toString methods get invoked; which one gets invoked first depends on the context. The result is necessarily a number or a string, though, so you can't add two objects and get an object back.

That said, there are hacks that can fake operator overloading in a function call context. For example, you can write something like this and get a reasonable result:

let x = Vector(1,2,3);
let y = Vector(4,5,6);
let z = Vector(7,8,9);
let sum = Vector(()=>x+y*z); // using * to mean dot product
// sum === Vector(122,244,366)

There are a couple of tricks. The first is that it overrides valueOf on Vectors to push this onto a stack. The second is that the function Vector looks at the number and kind of arguments it gets. When it gets a single function, it invokes the function, causing the variables to end up on the stack; then it uses the toString() method on the function to get the source code, it parses the source code, pops the actual vectors off the stack, computes the expression, then returns the result. Needless to say, this is terribly inefficient.

There are even uglier hacks that let you do away with the anonymous function, but going into the details is out of scope.