JS: Property Key "constructor"
Where Does the Constructor Property Came From?
By spec, every function has a Property Key "prototype" (except Arrow Function ) .
For user-defined function f, the value of f.prototype
by default is {"constructor":f}
(that is, a object with one property key "constructor"
, with value of the function itself).
// every function has a property key "prototype" (except arrow fuction) function FF() {} console.log(FF.hasOwnProperty("prototype")); // its value is a object, with just 1 property console.log(Object.getOwnPropertyNames(FF.prototype).length === 1); // the property key is the string "constructor" console.log(FF.prototype.hasOwnProperty("constructor")); // value of the property key "constructor" is the function console.log(FF.prototype.constructor === FF);
When you create a object using new
as in jj = new FF()
, the newly created object jj does not have a property key "constructor"
, but inherits from its parent, which is FF.prototype
.
Let's be more precise:
- Let there be a function FF, whose return value is not a object. (that is, no
return
statement, or explicitlyreturn
a non-object. 〔see Object Type〕) - The function FF is used with Operator “new”, as in
jj = new FF()
to create a object. - The parent of jj, has a property key
"constructor"
.
function FF() {} const jj = new FF(); console.log(jj.hasOwnProperty("constructor") === false); console.log(Reflect.getPrototypeOf(jj).hasOwnProperty("constructor"));
Purpose
The constructor property is meant to let you find the creator function of a object. (but is not reliable.)
Here is a typical way constructor property is used.
// typical use of constructor property function FF() {} const jj = new FF(); console.log(jj.constructor === FF);
Value of the Property Key "constructor"
It can be anything user sets.
Let's say you have user-created object named jj. You want to know what's the value of jj.constructor
.
Normally, jj itself does not have a property key "constructor"
. But jj's parent object usually does.
jj's parent object, let's call it pp, may have a proprety named “constructor”, and its value, by default, is a function FF that created jj by jj = new FF();
.
function FF() {} const jj = new FF(); const pp = Reflect.getPrototypeOf(jj); console.log(jj.hasOwnProperty("constructor") === false); console.log(pp.hasOwnProperty("constructor")); console.log(pp.constructor === FF);
Do Not Use the Constructor Property
There's no reliable way to find a object's creator function. Because:
- The value of the property key
"constructor"
can be changed anytime. - User can add/remove a property key
"constructor"
- The parent object of a object can change anytime. 〔see Get Set Prototype〕
- JavaScript objects are often created without a constructor. 〔see Create Object〕
〔see What is Constructor?〕
Here is a example. Setting a parent will offset the constructor value.
// the value of the property key "constructor" is not guaranteed to be the constructor function const jj = {}; function FF() {} FF.prototype = jj; const xx = new FF(); console.log((xx.constructor === FF) === false);
Standard Object's Constructor
For JavaScript's standard objects, using the constructor property is reliable (but is not very useful other than understanding how it works)
// showing array's constructor const aa = []; console.log(aa.hasOwnProperty("constructor") === false); console.log(Reflect.getPrototypeOf(aa) === Array.prototype); console.log(Array.prototype.hasOwnProperty("constructor")); console.log(Array.prototype.constructor === Array); console.log(Array.prototype.constructor === aa.constructor); // showing a date object's constructor const dd = new Date(); console.log(dd.hasOwnProperty("constructor") === false); console.log(Reflect.getPrototypeOf(dd) === Date.prototype); console.log(Date.prototype.hasOwnProperty("constructor")); console.log(Date.prototype.constructor === Date); console.log(Date.prototype.constructor === dd.constructor); // showing a function object's constructor const ff = function () {}; console.log(ff.hasOwnProperty("constructor") === false); console.log(Reflect.getPrototypeOf(ff) === Function.prototype); console.log(Function.prototype.hasOwnProperty("constructor")); console.log(Function.prototype.constructor === Function); console.log(Function.prototype.constructor === ff.constructor); // Showing a data object's constructor const jj = {}; console.log(jj.hasOwnProperty("constructor") === false); console.log(Reflect.getPrototypeOf(jj) === Object.prototype); console.log(Object.prototype.hasOwnProperty("constructor")); console.log(Object.prototype.constructor === Object); console.log(Object.prototype.constructor === jj.constructor); // showing a RegExp object's constructor const rr = /x/; console.log(rr.hasOwnProperty("constructor") === false); console.log(Reflect.getPrototypeOf(rr) === RegExp.prototype); console.log(RegExp.prototype.hasOwnProperty("constructor")); console.log(RegExp.prototype.constructor === RegExp); console.log(RegExp.prototype.constructor === rr.constructor);
JavaScript, Constructor, Class
- JS: thisBinding
- JS: What is Constructor
- JS: Property Key "prototype"
- JS: Operator “new”
- JS: instanceof Operator
- JS: Property Key "constructor"
- JS: Difference Between typeof, instanceof, constructor property
- JS: Class
- JS: Class Syntax
- JS: Class Expression
- JS: typeof Class
- JS: Keyword “static” (static method)
- JS: Keyword “extends”
- JS: Keyword “super”
- JS: Define a Class Without Using Keyword class