JS: prototype (property)

By Xah Lee. Date: . Last updated: .

Where Does Property Key Prototype Came From

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

// every function defined by keyword function has a property key "prototype"
console.assert((Object.hasOwn(function () {}, "prototype")) === true);

// arrow function does not
console.assert(Object.hasOwn((x) => (x + 1), "prototype") === false);

also, builtin constructors all have property key "prototype"

// builtin constructors
console.assert((Object.hasOwn(Function, "prototype")) === true);
console.assert((Object.hasOwn(Array, "prototype")) === true);
console.assert((Object.hasOwn(Object, "prototype")) === true);
console.assert((Object.hasOwn(Date, "prototype")) === true);

Purpose

The property key "prototype" is a mechanism for object created using Constructor to link to a parent.

// create a constructor
function Xcons() {}

// create a object
const jj = new Xcons();

// check the parent object is Xcons.prototype
console.assert(Reflect.getPrototypeOf(jj) === Xcons.prototype);

You can change the prototype before calling constructor, so that the newly created object's parent is that value.

F.prototype = obj

Default Value of Property Key "prototype"

For user-defined function f, the value of f.prototype by default is a newly created data object {"constructor":f}.

// Default Value of Property Key "prototype"

// every constructor has a property key "prototype"
function Xcons() {}
console.assert((Object.hasOwn(Xcons, "prototype")) === true);

// value of Xcons.prototype
const xx = Xcons.prototype;

// its value is a data object
console.assert(Reflect.apply(Object.prototype.toString, xx, []) === "[object Object]");

// with just 1 property
console.assert(Object.getOwnPropertyNames(xx).length === 1);

// the property key is "constructor"
console.assert((Object.hasOwn(xx, "constructor")) === true);

// the value of the property key "constructor" is the function
console.assert(xx.constructor === Xcons);

// show its attributes

// normal. use local variable
{
 const xdesc = Reflect.getOwnPropertyDescriptor(xx, "constructor");
 console.assert(Reflect.get(xdesc, "writable") === true);
 console.assert(Reflect.get(xdesc, "enumerable") === false);
 console.assert(Reflect.get(xdesc, "configurable") === true);
}

// show its parent
console.assert(Reflect.getPrototypeOf(xx) === Object.prototype);

〔see constructor (property)

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.

// 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.assert(Reflect.getPrototypeOf(new Object()) === Object.prototype);
console.assert(Reflect.getPrototypeOf(new Function()) === Function.prototype);
console.assert(Reflect.getPrototypeOf(new Array()) === Array.prototype);
console.assert(Reflect.getPrototypeOf(new Date()) === Date.prototype);
console.assert(Reflect.getPrototypeOf(new RegExp()) === RegExp.prototype);

Standard Constructor's Prototype Property Cannot be Changed

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

console.assert(Reflect.getOwnPropertyDescriptor(Array, "prototype").writable === false);

〔see Property Attributes

JavaScript. Constructor, Class