Absolutely fascinating. I'm still getting my head around the intricacies of why certain things are the way they are in JS (I'm self-taught with no academic background in compsci or anything like that), so thanks for helping.
Following that logic, I checked out the behaviour of Array, and that follows the same rules:
% Object.getPrototypeOf([])
[]
Using Object.getOwnPropertyNames shows what I was originally expecting RegExp.prototype to return (albeit as an array of strings rather than an object), but after reading all of the above, it's clear to me why it doesn't behave as I was expecting it to:
% Object.getOwnPropertyNames(RegExp.prototype)
["toString", "multiline", "exec", "constructor", "source", "ignoreCase", "compile", "global", "test", "lastIndex"]
I guess my main intrigue for all of this originally came from how JS's global objects appear "at source" (if that's the correct term?). For example, if I were to write out the Array object, I'd write something like the following (in its most basic form, anyway):
function Array() {} // The constructor (allowing for `new Array()` usage (IMO, not in-keeping with the rest of JS)).
Array.isArray = function() {}; // A "class" method.
Array.prototype.push = function() {}; // A prototype method.
I've left out arguments, the vast majority of the methods/properties, any inherited methods/properties, and haven't defined things as writable, enumerable, or configurable, but in my head that's how an Array would look. Is that a good way of thinking about it, or am I on completely the wrong track? I'm aware that global objects probably aren't presented like that (V8, at least, compiles to machine code before executing JS, so global objects might not even be described in Javascript), but behaviour-wise..?
Thanks, and I hope this isn't too simplistic!