Top 5 Ways JavaScript Pisses Me Off
by Jeff on
Please note this is a satirical piece written so professional JS developers can laugh at my lack of formal JS training. I agree every language has gotchas, but I am of the opinion that these "gotchas" are just bad design.
I will continue to update this post as I get more pissed off with JavaScript.
Numbers are only 53 bits
If you want to use a 64-bit integer, go fuck yourself. Alternatively, store it in a string.
There are too many ways to define a function
Is the normal
int add(int x, int y)
too boring? Lucky for you, JS has a plethora of ways to define a function and they all have the same outcome.function add(x, y) {
return (x + y)
}
const add = function(x, y) {
return (x + y)
}
const add = (x, y) => {
return (x + y)
}
const add = (x, y) => (x + y)
Abstract vs strict equality comparison
(or, for us commonfolk, double equals vs triple equals)
This isn't as bad as some of the other stuff, but it can lead to some really weird behavior. Since JS is loosely typed, the double-equals operator tries normalize types before comparing. This means expressions like
10 == '10'
are truthy, even though int
and string
should not be directly comparable, let alone equal.You can exploit the desire to normalize type by making your own
.toValue()
method. This allows even stranger behavior like a == 1 && a == 2 && a == 3
to be truthy.Mismatched type concatenation
Again, this has to do with JS's desire to normalize types. Consider the following pseudo-code.
a := 2 b := "3.5" c := a + b print(c)
The astute among you may have noticed
a
and b
are different types. Different languages handle this differently.// C
...
int main() {
int a = 2;
char b[] = "3.5";
int c = a + b;
printf("%d\n", c);
}
$ gcc -g -Wall test.c -o test
test.c: In function 'main':
test.c:5:13: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
int c = a + b;
^
$ ./test
-1107732586
// Go
...
func main() {
a := 2
b := "3.5"
c := a + b
fmt.Println(c)
}
$ go run main.go
./main.go:5:9: invalid operation: a + b (mismatched types int and string)
I like these languages because they do exactly what I told them to do. Go just lets me know that I messed up. C assumes I didn't mess up and adds an
int
to the pointer that b
stores. Compare that to JS.// JS
a = 2
b = "3.5"
c = a + b
console.log(c)
$ node app.js
"23.5"
JS "cleverly" converted the
int
into a string
, then concatenated the two. In this particular instance, some may argue it's a "feature". It doesn't stop there.// JS
a = 2
b = {
value: "3.5",
hello: "world"
}
c = a + b
console.log(c)
$ node app.js
"2[object Object]"
Absolutely useless.
Made-up operators
Examples include the nullish coalescing operator (
??
) and the optional chaining operator (?.
). These two operators (and I'm sure there are more) are shorthand for edge cases that save (at most) a few lines of code.The following example illustrates how the nullish coalescing operator can be replaced with a ternary operator for just 37 more characters (and 100% more readability).
// nullish coalescing operator
const res = null
const foo = res ?? 'default string'
console.log(foo)
// output: "default string"
// ternary operator
const res = null
const foo = (res === null || res === undefined) ? 'default string' : res
console.log(foo)
// output: "default string"
On a side note, I asked a coworker who's been using computers since before the Internet if he knew what a nullish coalescing operator was. His immediate response: "that must be a JS thing."
Back to All Posts
Back to Home