JS: Property Key "prototype"

By Xah Lee. Date: . Last updated: .

In JavaScript, every function has a magical property key "prototype".

( except arrow function [see JS: Arrow Function] )

// every function has a property key "prototype"

// standard function objects
console.log ( Function.hasOwnProperty ( "prototype" ) ); // true
console.log ( Array.hasOwnProperty ( "prototype" ) ); // true
console.log ( Object.hasOwnProperty ( "prototype" ) ); // true
console.log ( Date.hasOwnProperty ( "prototype" ) ); // true

// user-defined function
console.log( (function () {}).hasOwnProperty("prototype") ); // true

console.log( ((x) => (x+1)).hasOwnProperty("prototype") ); // false

[see JS: Property Overview]

// prints all global function objects and report if they have key "prototype"

(
    ( Reflect.ownKeys ( window ) ).forEach (
        (x) => {
            if ( typeof window[x] === "function" ) {
                if ( window[x].hasOwnProperty ( "prototype" ) ) {
                    console.log ( "yes", x );
                } else { console.log ("no", x ); }
            }
        }
    )
)

// if running in nodejs, replace 「window」 by 「global」

The value of a property key "prototype" of a object X is NOT the prototype (aka parent) of object X. (it's possible to make it so, but that basically never happens.)

[see JS: Prototype and Inheritance]

Where Does it Came From?

Every function has a property key "prototype", by spec.

ECMAScript 2015 §ECMAScript Language: Functions and Classes#sec-function-definitions-runtime-semantics-evaluation

Purpose

The property key "prototype" is a mechanism for object created using new F() to link to a parent.

You can set a function F's prototype property F.prototype = obj before calling new F(), so that the newly created object's parent will be obj.

[see JS: Operator “new”]

// ff.prototype is parent of 「new ff()」, at time of call of 「new ff()」

function ff () {};

const x = new ff();

console.log(
    Object.getPrototypeOf(x) === ff.prototype
); // true

// note: provided ff does not return a object in definition

[see JS: Create Object with Parent X]

Default Value

For user-defined function f, the value of f.prototype by default is a newly created object {"constructor":f} (that is, a newly created object, with only one property key, this property key is named "constructor", and value of property key "constructor" is the function itself. The parent of this newly created object, is Object.prototype). ECMAScript 2015 §Ordinary and Exotic Objects Behaviours#sec-makeconstructor

// every function has a property key "prototype"
function FF() {};
 console.log ( FF.hasOwnProperty("prototype")
); // true

// its value is a object, with just 1 property
console.log (
 Object.getOwnPropertyNames(FF.prototype).length === 1
); // true

// the property key is "constructor"
console.log (
 FF.prototype.hasOwnProperty ( "constructor" )
); // true

// the value of the property key "constructor" is the function
console.log ( FF.prototype.constructor === FF ); // true

// show its attributes
console.log (
 Object.getOwnPropertyDescriptor( FF.prototype, "constructor" )
);
// { value: [Function: FF],
//   writable: true,
//   enumerable: false,
//   configurable: true }

// show its parent
console.log ( Object.getPrototypeOf ( FF.prototype ) === Object.prototype ); // true

[see JS: Property Key “constructor”]

Builtin Function's Value of Property Key "prototype"

For any JavaScript's buildin constructor B, the value of B.prototype is a object, and the only way to express that object is just via the “prototype” property access, that is B.prototype.

For example:

And, just like user-defined function, the following is true:

For any JavaScript's buildin constructor B, the parent of new B(…) is always B.prototype. Because the value B.prototype can never change.

console.log (
 Object.getPrototypeOf ( new Object() ) === Object.prototype
); // true

console.log (
 Object.getPrototypeOf ( new Function() ) === Function.prototype
); // true

console.log (
 Object.getPrototypeOf ( new Array() ) === Array.prototype
); // true

console.log (
 Object.getPrototypeOf ( new Date() ) === Date.prototype
); // true

console.log (
 Object.getPrototypeOf ( new RegExp() ) === RegExp.prototype
); // true

Standard Constructor's Prototype Property Cannot be Changed

Standard constructor's prototype property cannot be changed, because its writable attribute is false.

// Standard constructor's prototype property cannot be changed, because its writable attribute is false
console.log(
    Object.getOwnPropertyDescriptor(Array, "prototype")
 );

// prints
// { value: [],
//   writable: false,
//   enumerable: false,
//   configurable: false }

[see JS: Property Attributes, writable, enumerable, configurable]

Changing it results in error.

// builtin constructor's prototype property cannot be changed
"use strict";

Array.prototype = {};

// Array.prototype = {};
//                 ^

// TypeError: Cannot assign to read only property 'prototype' of function Array() { [native code] }

JS Constructor Topic

  1. JS: “this” Binding
  2. JS: What's Constructor?
  3. JS: Property Key "prototype"
  4. JS: Operator “new”
  5. JS: “instanceof” Operator
  6. JS: Property Key “constructor”
Liket it? Put $5 at patreon.

Or, Buy JavaScript in Depth

Patreon me $5. Ask me question on patreon