🚧printPrototypeChain()
🚧 under construction -> improve with TableMaker, make it a method.
JS ⟩ types ⟩ object ⟩ prototype chain ⟩ print
replit: printPrototypeChainOf()
require: Iterator, isPrimitive(), typeName(), TableMaker
// importimport
const Iterator = require('./IteratorPrototype.js');
const { isPrimitive } = require('./isObject.js');
const { typeName } = require('./typeNames.js');
const { log } = console;
// ⭐️ prototype chain of value
function printPrototypeChainOf(value, name, {
typeWidth=12, // "type" column width
noteWidth=23, // "note" column width
valueWidth=28, // "value" column width
prototypes=[], // custom prototypes, format:
// {value: <value>, name: <name>}
}={}) {
// if not an object, do nothing
if (isPrimitive(value)) {
log(`ℹ️ value: ${value} is not an object.`);
return;
}
// keep the original object for reference
const original = value;
// column widths
const widths = {
type: typeWidth,
note: noteWidth,
value: valueWidth,
cols: 3, // # of columns
pad: 1,
get total() {
return this.type + this.note + this.value + (this.cols - 1) * this.pad
}
};
// separator line
const line = '-'.repeat(widths.total);
const arrow = '→ ';
// 🔸 print row
function print(type, note='', value='') {
const items = [
type.padEnd(widths.type, ' '),
note.padEnd(widths.note, ' '),
value,
];
log(...items);
}
// table header
log(`🌟 Prototype Chain of: `, name);
log(line);
print(` type`, `prototype chain`, `value`);
log(line);
// 🌟 builtin prototypes
const builtinPrototypes = [
{value: Object.prototype, name: 'Object.prototype', hideValue: true},
{value: Array.prototype, name: 'Array.prototype', hideValue: true},
{value: Function.prototype, name: 'Function.prototype', hideValue: true},
{value: Iterator.prototype, name: 'Iterator.prototype', hideValue: true},
];
// 🔸 known prototype ?
function proto(obj) {
prototypes = builtinPrototypes.concat(prototypes);
type = '• ' + typeName(obj);
const result = {type: type, name: '(?)', value: obj }
// test for prototypes
for (const p of prototypes) {
if (p.value === obj) {
result.name = p.name;
if (p.hideValue) result.value = '';
break;
}
}
result.name = arrow + result.name;
return result;
}
// while value !== null, print it out
while (value) {
let p = proto(value);
if (value === original) p.name = name;
print(p.type, p.name, p.value);
value = Object.getPrototypeOf(value);
}
// now, value === null
print(`• Null`, arrow + '❌', 'null');
log(line+'\n');
}
// export
module.exports = {printPrototypeChainOf};
replit: printPrototypeChainOf()
// import
const { printPrototypeChainOf } = require('./prototypeChain.js');
// object literal
var obj = {a:1};
// custom classes
class A {}
class B extends A {};
let a = new A();
let b = new B();
// generator function
function* gen(){}
// log
[
{value: obj, name: 'obj'},
{value: [1,2], name: '[1,2]'},
{value: function foo(){}, name: 'foo'},
{value: gen(), name: 'gen()'},
{value: a, name: 'new A()'},
{value: b, name: 'new B()'},
].forEach(x =>
printPrototypeChainOf(x.value, x.name, {
// typeWidth: 15,
// valueWidth: 28,
prototypes: [
{value: A.prototype, name: 'A.prototype', hideValue: true},
{value: B.prototype, name: 'B.prototype', hideValue: true},
]
})
);
replit: printPrototypeChainOf(), (require:TableMaker)
🌟 Prototype Chain of: obj
-----------------------------------------------------------------
type prototype chain value
-----------------------------------------------------------------
• Object obj { a: 1 }
• Object → Object.prototype
• Null → ❌ null
-----------------------------------------------------------------
🌟 Prototype Chain of: [1,2]
-----------------------------------------------------------------
type prototype chain value
-----------------------------------------------------------------
• Array [1,2] [ 1, 2 ]
• Array → Array.prototype
• Object → Object.prototype
• Null → ❌ null
-----------------------------------------------------------------
🌟 Prototype Chain of: foo
-----------------------------------------------------------------
type prototype chain value
-----------------------------------------------------------------
• Function foo [Function: foo]
• Function → Function.prototype
• Object → Object.prototype
• Null → ❌ null
-----------------------------------------------------------------
🌟 Prototype Chain of: gen()
-----------------------------------------------------------------
type prototype chain value
-----------------------------------------------------------------
• Generator gen() Object [Generator] {}
• Generator → (?) Object [Generator] {}
• Generator → (?) Object [Generator] {}
• Object → Iterator.prototype
• Object → Object.prototype
• Null → ❌ null
-----------------------------------------------------------------
🌟 Prototype Chain of: new A()
-----------------------------------------------------------------
type prototype chain value
-----------------------------------------------------------------
• Object new A() A {}
• Object → A.prototype
• Object → Object.prototype
• Null → ❌ null
-----------------------------------------------------------------
🌟 Prototype Chain of: new B()
-----------------------------------------------------------------
type prototype chain value
-----------------------------------------------------------------
• Object new B() B {}
• Object → B.prototype
• Object → A.prototype
• Object → Object.prototype
• Null → ❌ null
-----------------------------------------------------------------
ObjectPlayground - visualize prototype chain (cool ⭐️)
Last updated