const { log } = console;
const descriptor = (obj, prop) => log(Object.getOwnPropertyDescriptor(obj, prop));
const descriptors = (obj) => log(Object.getOwnPropertyDescriptors(obj));
// โญ function ---------------------------------------------------------
function F(name) {
this.name = name;
}
descriptors(F);
// property w e c value
// ---------------------------------
// length x x o 1
// name x x o 'F'
// arguments x x x null
// caller x x x null // ------------------------------------
// prototype o x x F {} ? --------> // โญ ๆณจๆ๏ผ
// --------------------------------- // F.prototype ๆฏ writableโ
// w: writable (can reassign) // ไนๅฐฑๆฏ่ชช๏ผF.prototype ๆฏๅฏไปฅ่ขซๆๆ็โ
// e: enumerable (listed in for loops) // ------------------------------------
// c: configurable (can delete or change flags)
// โญ every function has a default prototype
descriptors(F.prototype);
// property w e c value
// -----------------------------------
// constructor o x o [Function: F]
// -----------------------------------
log(F.prototype.constructor === F); // true
// new object from F // "-->" means "prototype chain"
let obj = new F("object"); // obj --> default prototype
log( obj.eats ); // `undefined`
// object as new F.prototype
let animal = {
eats: true
};
// โญ overwrite function's default prototype
F.prototype = animal;
log(F.prototype.constructor); // `Object` (via prototype chain)
log(F.prototype.constructor === Object); // true
// new object from F (again)
let obj2 = new F("object 2"); // obj2 --> animal
log( obj2.eats ); // true
// โญ class ---------------------------------------------------------
class A {}
descriptors(A);
// property w e c value
// ---------------------------------
// length x x o 0
// name x x o 'A' // ----------------------------------------
// prototype x x x A {} -------> // โญ ๆณจๆ๏ผ
// --------------------------------- // A.prototype ็ writable == falseโ
// ไนๅฐฑๆฏ่ชช A.prototype ๆฏใไธ่ฝใ่ขซๆๆ็โ
descriptors(A.prototype); // ----------------------------------------
// property w e c value
// -----------------------------------
// constructor o x o [class A]
// -----------------------------------
const proto = A.prototype;
log( proto === A.prototype ); // true
// instances of class A
let a = new A();
// โญ `A.prototype` is non-writableโ
const newProto = {};
// ----------------------------------------------------------------
A.prototype = newProto; // โญโญโญ A.prototype ็กๆณๆๆโโโ
// ----------------------------------------------------------------
log( A.prototype === newProto ); // โญ falseโ
log( A.prototype === proto ); // true
log( A.prototype.constructor ); // [class A]
// console
[
// `A` is a function.
A.__proto__ === Function.prototype, // true
// every function has a "default prototype".
A.prototype !== null, // true
A.prototype.constructor === A, // true
// new object's [[Prototype]] is set to `A.prototype` automatically
a.__proto__ === A.prototype, // true
// object's constructor can be found through its "prototype chain".
// (provided its [[Prototype]] hasn't been overridden already)
a.constructor === A, // true
].forEach(x => log(x));