These functions, in my opinion, should all throw if you didn't provide an explicit argument, because it's not clear what they should do in the first place.
While you said a lot here, it only shows that you might not understand the point of a default constructor in an object. A default constructor is supposed to give you back a fully initialized value in an acceptably "neutral" state. That means for
String() it should give back an empty string. How is that neutral? What it gives back must be a string, but cannot have any content as none was specified. The same goes for
Number(). It must give back a number. The only existing number that can be thought of as "neutral" reasonably is
0 since it is its own negative. Likewise
Symbol() must return a
Symbol. The problem here is that there isn't even a concept of a "neutral" value when it comes to
Symbols. So in this case, the constructor must return a fully ready-to-use value. This is the reason
BigInt() should return
The problem with
BigInt(undefined) IMO is that it should be parallel to something like this:
let a = BigInt(); //Create an initialize a BigInt to a neutral value
a.setValue(undefined); //Imagining BigInt had a setValue function
The second line should either throw or assign
a as there is no
BigInt value equivalent to
void 0. Likewise, the constructor call
BigInt(undefined) should throw as it is being told to initialize itself to a value for which it has no equivalent.
As for why someone would use
0n, it could be because they want to use pre-boxed values. The constructors return an
Object, not a primitive (except Symbol, which is why I don't balk at it not having a
new Symbol() equivalent). This has certain advantages, such as the ability (though weird and possibly considered an anti-pattern) to attach functions and data.
I find it rather disturbing that there is a growing pressure on the language to defend against developer mistakes that can "introduce nasty bugs" in lieu of a growing pressure on developers to understand how to use the language. Making the language take up the role of developer nanny only forces limitations on the language that encroach on its usefulness. Making the developer take up responsibility for learning how to use a language well leads to more innovative achievements and a more flexible, more capable language. All-in-all, I don't understand arguments like the one you gave.