Some reasons I do not like javascript

It is no secret that Javascript isn't the most well-designed language, and these points have probably been made a billion times, but now it's my turn!

Note that this isn't a criticism about a lack of expressiveness. You can create great things with javascript. But you can also footgun yourself very easily, which is what I'm criticizing there. Most languages are expressive, but good ones help you avoid mistakes instead of making them.

  • You can pass more or fewer arguments to a function than it takes parameters:

    function f(x, y) {
      console.log(x, y, arguments[2], arguments[3]);
    }
    f()  // undefined undefined undefined undefined
    f(1, 2)  // 1 2 undefined undefined
    f(1, 2, 3, 4)  // 1 2 3 4
    

    Why make it so easy to let mistakes go unnoticed, when they could have been reported easily?

    It can occasionally be useful, but can be done much better with default parameter values or varargs in other languages.

  • Omitting var puts things in global scope:

    function a() {
      p = 5
    }
    function b() {
      console.log("p =", p)
    }
    a()
    b()
    
  • Every number is secretly a float64:

    9007199254740992 + 1
    // 9007199254740992
    

    This happens because 2^53 is the highest exact whole float64

    Other languages have overflows, which suck, but Javascript has somehow managed to do even worse.

  • Objects use toString as 'hash' function and don't check equality (info):

    function P (a) {
      this.a = a
    }
    o1 = new P(1)
    o2 = new P(2)
    var q = {}
    q[o1] = 42
    console.log(q[o2])
    // 42
    

    The keys are clearly different, but the 'map' doesn't notice.

    (ECMA 6 maps have the opposite problem: cloned objects do not form the same key)

  • It does automatic type conversion:

    // these are all true
    console.log(undefined == null);
    console.log("0" == 0);
    console.log("" == 0);
    console.log("\n\r\t" == 0);
    console.log(false == [0]);
    console.log(![] == []);
    console.log(![0] == [0]);
    console.log([]+[] === "");
    console.log(Array(3) == ",,");
    

    Yes, most of this can be avoided with ===. First, they should have been the only way. Second, it does not only apply to equality checks:

    var q = [42];
    console.log(q["0"]);
    

    There are other times when it just assumes something when what you ask for is just invalid:

    var p = [];
    p[10] = 42;
    console.log(p); // [ <10 empty items>, 42 ]
    

    And as mentioned, numbers are all of the same type, so no coercion needed there.

  • Missing things are (sometimes) undefined instead of errors:

    a = {b: 9}
    console.log(a.c) // undefined
    function d(e) {
      console.log(e) // undefined
    }
    d()
    e = [1,2]
    console.log(e[2]) // undefined
    console.log(f)  // this IS an error
    

    It is nice that there is at least a difference between undefined and null, but it doesn't follow the fail fast principle.

  • What does 'this' refer to?

    It is easy in most languages with objects, but javascript is not like most languages with objects.

    • Without context, it's the window/global scope
    • When called on an object as x.f(), x is this inside f (note that the same function can be called on various objects)
    • this can be changed with call, apply or bind.
    • When using 'private methods', you need to rebind this, or use call everywhere.
    • Then there's jQuery.

    This page goes over the different cases well.

  • There is no convenient way to implement your own hashcode, equality checks, overloaded arithmetic, etc.

  • Some of the built-in functions are just silly, like parseInt and string.replace.

Many of these were less serious problems when javascript was young, and still only used for 5-line scripts. But in my opinion, none of them were ever good ideas. And they were done right in languages far predating javascript, so they could've been done correctly in javascript.

Let us hope that WebAssembly kills javascript soon!

Comments

No comments yet

You need to be logged in to comment.