Search code examples
javascriptprototypeinternals

Why can you not set the prototype of builtin objects in javascript?


I'm trying to get behind javascript internals and prototyping at the moment. One thing that's tripping me up at the moment is that when I assign Object.prototype to something, it doesn't seem to actually do anything, as opposed to when I do the same for functions I define (Likewise for other builtins like Function.prototype). So I get some unexpected results when I run the following in my browser:

function A() {};
typeof A // "function"
console.log(A.prototype); // {constructor: ƒ} etc
A.prototype = null
console.log(A.prototype); // null
typeof Object // "function"
Object.prototype // {constructor: ƒ} etc
Object.prototype = null
Object.prototype // still {constructor: ƒ} etc, not null

Why is that? Is it simply by definition, so Object.prototype is always the same no matter what? And if so, does my assignment of Object.prototype actually do anything?

And, perhaps this is a subjective question, but if so, why doesn't this throw an error then?


Solution

  • Is it simply by definition, so Object.prototype is always the same no matter what?

    Yes. From the specification:

    19.1.2.19 Object.prototype

    The initial value of Object.prototype is %Object.prototype%.

    This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

    [[Writable]] being false means you can't change it via assignment. [[Configurable]] being false means you can't redefine it via defineProperty.

    That's true of the prototype property of all the built-in constructors.

    And if so, does my assignment of Object.prototype actually do anything?

    No, nothing at all.

    And, perhaps this is a subjective question, but if so, why doesn't this throw an error then?

    Because you're using loose mode. :-) In strict mode, you'd get an error for it, because assigning to a read-only property in strict mode is an error:

    "use strict";
    Object.prototype = null;

    I suggest always using strict mode. These days, you do that by using JavaScript modules (which are strict mode by default).