Operator Overloading in JavaScript, yes you can!

Adam Crockett šŸŒ€ - Jan 7 '20 - - Dev Community

It struck me that it would be nice to have some form of ByteString in JavaScript utilizing TextEncoder but instead of having some fancy newing up and going through a couple of hoops to make something that couldn't be handled like a string anymore what if a user could just do this.

b`hello world`;
Enter fullscreen mode Exit fullscreen mode

And here is what the idea is based on, Rust's byte string.

b"hello rustations";
Enter fullscreen mode Exit fullscreen mode

The JavaScript version would take on the form of a tagged function for a template literal, that's cool in itself, it never occurred to me that we could make such psudo primitive types. Okay what would the Byte string return? In theory it should return a Uint8Array of unicode utf8 encoded bytes, this is all doable so far. But what if I want to concatinate them?

JavaScript doesn't officially offer the ability to change what + does, but a couple of languages do, this is known as operator overloading, changing an oporators behaviour on a type that you own. Therefore if I want to do:

b`hello` + b`world` // TypedArray + TypedArray šŸ˜µ
Enter fullscreen mode Exit fullscreen mode

Unfortunately though this is possible it does mean that I must provide the return value as part of an API, remember the result of this string notation is Not a string, it's a Uint8Array, you cannot add 2 TypedArrays together, so the API version could be kind of useful, a bunch of methods on my type would make it feel just a bit more native.

Here's how it's done:

function b(str) {
   const _value = str[0];
   return {
      _value,
      toUtf8Bytes() {
         return new TextEncoder().encode(_value)
      },
      valueOf() {
         // When the interpreter asks for the value of this object we give it the original string.
         return _value;
      }
   }
}
Enter fullscreen mode Exit fullscreen mode

The valueOf overides the method used by the interpreter to compute and display values in Console etc etc, as far as JavaScript is concerned, this is a regular string, Meaning that any time I do use any operator, the valueOf will be called like a setter getter. In my example in fact it's like I'm adding 2 objects together but tricking the interpreter into thinking it's a string. Don't worry if this is safe, everything is an object in JavaScript anyway it's not that wierd. What would work even better would be a es6 class instance of ByteString extending String, Anyway I found this absolutely fascinating and could be an incredible technique, I hope you did learn something too.

But why?

Post note, you can use interpolation syntax with this (with some modifications as to how you put the pieces back together) and pass this to webgl or Wasm really easily.

If byte strings are not your thing, what about a Vector class instance you could just add together or an abstraction of the CSSOM units, I can think of a lot of cool uses for this ahem hack.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player