Mixed Methods for Mastery
If you are seeking to dive further into a programming language, and you decide to ask an expert, oftentimes you will get the same advice given. In fact, in the few years of my life, I repeatedly have heard many sentiments about learning programming languages:
- You need to go back through the docs and read everything, and read it well. Otherwise you won’t know what features to use when.
- You need to find and complete numerous different coding practices and projects with that one language to have enough experience to master it.
- You need to find and follow an informed guide, lecture, or course and stick to it. In the end, you will know all of your fundamentals alongside the foresight and wisdom of the person who taught you.
The reason these sentiments are repeated is because… they work! If learning a new programming language seems daunting to you, I would highly recommend trying out your pick of the aforementioned methods, as they have worked for me and undoubtedly worked for many before me. However, today, I am here to talk about the unconventional way I was able to use a language/limitation called “JSFuck” to learn many important concepts in JavaScript.
JavaScript and its Numerous Typing Issues.
Before I talk about JSFuck and how it helped me, I should first explain some of the issues in JavaScript that lend to the story. It shouldn’t really be controversial to say that JS type conversion and comparison is unconventional (or at least unexpected).
If you were to ask me, many programmers’ JavaScript typing issues stem from using the plus operator. The +
in JavaScript has the ability to concatenate strings and arrays, cast anything into a number, and of course add numbers together. This leads to some very unexpected results when someone wishes to add two numbers, but one of them is a string. Though this sounds niche and nitpicky, it is rather frequent when somewhere back in the code a number was expected and a string with numeric content was provided.
Some Examples
Let’s say I’m a beginner trying to shift an array right by one key or index position. I may understandably, but naively, just use a “for…in” loop to go through the indexes adding one to the index in a new array, but since JS stores the keys as strings, this has a unintuitive result.
let original_array = [5, 6, 7];
let shifted_array = [];
for(let i in original_array){
shifted_array[i + 1] = original_array[i];
}
Instead of the keys being added together, they are concatenated.
So instead of index 1 + 1
equalling index 2
, it equals index 11
(since it actually is "1" + 1
). This means that our final array wasn’t [undefined, 5, 6, 7]
as expected, and actually was more like ({"01":5, "11":6, "21":7})
.
Since, as long as you know it exists, you can choose from a variety of ways to typecast or solve your issue, this specific example isn’t really a major issue when programming in a professional setting. The true concern in a professional setting is making sure to fully learn how all of the different types and operators interact. It’s also of course important to work with people to understand the delicate typing situation in JavaScript, since that isn’t explicitly included in much documentation and can seem janky or inconsistent when you first see it.
JSFuck and the gamification of learning programming
JSFuck is an esoteric programming language – basically, it’s among the ranks of impractical languages such as Hexagony (a 2d programming language) and joke languages like Shakespeare (where you code is literally a Shakespeare play).
JSFuck is not really in the same category as those examples, however. JSFuck is just JavaScript, but with one limitation The limitation is that you can only use 6 characters:
- Either Parenthesis – “(” and “)”
- Either Square Bracket – “[” or “]”
- Exclamation point – “!”
- Plus sign – “+”.
How even does +!![] code in JSFuck
I messed around learning JSFuck to supplement my learning of JavaScript back in 2016. I made it my mission to not look up how any of it worked and let my 15 year old brain get to work. I threw together a google doc (I still have it unaltered here if you wanna see what awful organization looks like) and started coming up with concise ways to represent as many letters and numbers as possible.
After many hours, across a few days, I became overwhelmed. I realized the uphill grind I was on to execute code in this syntax compared to simply returning text. Though disheartened to a slow stop then, I now realize that I gained more javascript knowledge working with JSFuck than I did through 3 projects prior to that. I learned that taking a hard concept and gamifying it is one of the most effective ways to force myself to learn my programming fundamentals.
Overusing JavaScript Casts & Operators in JSFuck
Let’s use the example to show how we would logically go through getting the letter t;
+[] // outputs 0, using unary number coercion
!![] // outputs true, using logical not
!![]+[] // outputs "true", "true" === true + []
(!![]+[])[+[]] // outputs "t", "t" === "true"[0]
Our only real object is an array. It’s worth noting that an array is truthy and casts numerically to 0
. Let’s break down the process of getting the letter t. It seems the most concise approach would be to take the “t” from the simple-to-cast-to boolean true.
We can get the initial boolean by using the logical not operator (the !) twice on the array. From here we want to cast “true” into a string so we can select the first letter of it. We do this by using the “+” operator to concatenate true and an empty array (ie. !![]+[] == "true"
). From there we simply wrap the expression in parentheses, and use the character selector to get the zeroth character in the string, which is our letter t.
Why is this a good thing?
This is an article talking about, and arguably promoting, bad programming. Of course it would never be good or advised to obfuscate or shorten away your code using type coercion. However, that isn’t to say that messing around with this typing is not important.
This random limitation that JSFuck implements on top of JavaScript helps you to really know different core concepts that even professional JavaScript Developers may not dig into the nitty gritty of: exact order of operation, type coercion, truthiness values, and how javascript comparison operators decide to convert types without you noticing.
This type of “hacking together” of a programming language really helps you further think through expressions the exact way the language will execute them. In fact, unexpected typing in JavaScript has provided me with many new, different ways of lateral thinking and has saved me immense amounts of debugging time. It has taught me that whenever dealing with keys or variables of unknown typing, explicit conversion is necessary. It has taught me that one plus one does equal two… but if you aren’t watching as closely as you should, it may equal eleven.