JavaScript Warts

By Xah Lee. Date: . Last updated: .

no real array

no real array. js array is object. you have the situation of array-like object, and sparse array.

Array Constructor problem

what it does depends on the arg type and number of args.

also, when given a single int arg, it does not actually generate a array, but a sparse array, so that when you use map to fill it, creates an error.

console.log(Array(3,4));
// [ 3, 4 ]

console.log(Array(3));
// [ <3 empty items> ]
console.log(Array(3).map((x) => x + 1));
// [ <3 empty items> ]

some Constructor does not require new operator

some Constructor does not require new operator, some do, some have same behavior, some not.

no equality test on array, nor object

you cannot compare array by content.

console.log( [1,2,3] == [1,2,3] )
// false

console.log( [1,2,3] === [1,2,3] )
// false
console.log( {p:1} == {p:1} )
// false

string is utf16 bytes

this means, all string methods, fail if the string contains emoji.

console.assert("🦋".length === 2);

no real type, they are just objects

function, regex, date, map, are all just object type.

by spec, they are all object type. this makes it a problem, because you need to know if a object is regex, date, map, etc.

however, typeof has an oddity that type of function return function. so, only for function, you can distinguish.

console.assert(typeof {} === "object");
console.assert(typeof (new Date()) === "object");
console.assert(typeof (new RegExp(".")) === "object");
console.assert(typeof ((x) => x) === "function");

many functions implicit convert type

// string plus array becomes array
console.assert("abc" + [3, 4] === "abc3,4")
// isNaN convert arg to number first
console.assert(isNaN("NaN"));

double equal implicit convert type

console.assert([] == "");
console.assert("0" == 0);
console.assert("" == 0);
console.assert(1 == true);

math function does not work with big int

// the ** operator supports bigint
console.assert(3n ** 2n === 9n);

// Math.pow() does not support bigint
try {
 Math.pow(3n, 2n);
} catch (xerr) {
 console.log(xerr);
}
// TypeError: Cannot convert a BigInt value to a number

many methods work on other type

odd and unintuitive and hard to use. no clear way to know which such method can be used on what other type.

// some function work on other type
console.log(Reflect.apply(String.prototype.repeat, ["a", "b", " "], [4]));
// a,b, a,b, a,b, a,b,

typeof null is object mistake

// null is object type
console.assert(typeof (null) === "object");

no integer type

const x = 9007199254740992;
console.assert(x === x + 1);

fixed by big int.

lots duplicate methods or syntax, one is improved of the other

Math.pow(x,y) vs x ** y

console.log(Array(3,4));
// [ 3, 4 ]

console.log(Array(3));
// [ <3 empty items> ]

console.log(Array.of(3,4));
// [ 3, 4 ]

Why JavaScript is the Suckest Language

JavaScript is truly the suckest language. There's no easy way to test object equality, forces you to change your code's algorithms, fundamentally.

and JavaScript syntax, is the worst possible. Code written by others is not readable.

why is js syntax unreadable? because

it has function expression, but it does not have the usual function programing languages's design to control it. JS is mostly imperative and prototype OOP, incompatible with function programing. Thus, you have passing function as argument and return function. This feature by itself, if used without fine control, creates incomprehensible code (e.g. y-combinator). (e.g. haskell has types, composition, currying, etc, to control complex function semantics.)

And JavaScript syntax is C/Java-like, provides no syntactic support for function programing. The passing function style becomes unreadable quickly. (e.g. lisp solves syntax problem by almost pure nested parenthesis, and haskell etc provides linear syntax (no parenthesis), and syntax that support semantic features such as currying, lambda, nesting, etc.)

Further, JavaScript design that was trying to emulate Java, created the following entities with exceptionally convoluted semantics.

been thinking, to fix the js problem by removing some features, we'd gain a lot by,

  1. Ban the keyword function.
  2. Ban the keyword this.
  3. Ban the keyword new.
  4. Ban the use of property key "prototype".
  5. Ban the use of property key "constructor".
  6. Ban the keyword delete. [see Delete operator]
  7. Ban the keyword var.
  8. Ban ==.

JavaScript sucks

Spec Reading
sucks
warts