Last active
August 29, 2019 07:05
-
-
Save wentout/47eb0fd224e69b65b3efddbcb6741408 to your computer and use it in GitHub Desktop.
Inheritance Map Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// Inheritance Map Example | |
const assert = require('assert'); | |
const { strictEqual, deepStrictEqual } = assert; | |
const util = require('util'); | |
const inspect = (value) => { | |
return util.inspect(value, { | |
colors : true, | |
compact : false | |
}) | |
}; | |
const userTypePrototypeDesc = 'User ETL~DFD: Init'; | |
const createUserType = function () { | |
var UserType = function({ email, password } = userData) { | |
this.email = email; | |
this.password = password; | |
return this; | |
}; | |
UserType.prototype.description = userTypePrototypeDesc; | |
UserType.prototype.email = ''; | |
UserType.prototype.password = ''; | |
return UserType; | |
}; | |
const UserWithoutPasswordTypePrototypeDesc = 'User ETL~DFD: No Password'; // used for checking, unnecessary | |
// so... it must be reproducible | |
const createNewUserWithoutPasswordType = function () { | |
const UserWithoutPasswordType = function() { | |
// delete this.password; | |
// does not work | |
// cause property deletion | |
// will cast prototype chain | |
// backing prop to place | |
// instead the following will | |
// cause we use memory block | |
// by setting it to undefined | |
// and, moreover, through this | |
// we will see our data change | |
// cause prop will exist | |
// but we changed it to undefined | |
// it is not rude, just SOLID | |
// and DFD ~ SADT transformations | |
// and ETL concept in rush :) | |
this.password = undefined; | |
return this; | |
}; | |
UserWithoutPasswordType.prototype.description = UserWithoutPasswordTypePrototypeDesc; // used for checking, unnecessary | |
return UserWithoutPasswordType; | |
}; | |
// so... it must be reproducible | |
const createNewUserDataTypeExampleModType = function () { | |
const UserWithExampleModificationType = function(initWith = 'none') { | |
this.modificationExampe = `done : ${initWith}`; | |
return this; | |
}; | |
return UserWithExampleModificationType; | |
}; | |
const createNewUserDataTypeExampleModTypeNext = function () { | |
const UserWithExampleModificationTypeNext = function(initWith = 'none') { | |
this.modificationExampeNext = `next : ${initWith}`; | |
return this; | |
}; | |
return UserWithExampleModificationTypeNext; | |
}; | |
const createMoreDeep = function () { | |
const MoreDeep = function(initWith = 'none') { | |
this.moreDeep = `moreDeep : ${initWith}`; | |
return this; | |
}; | |
return MoreDeep; | |
}; | |
const createEvenMoreDeep = function () { | |
const EvenMoreDeep = function(initWith = 'none') { | |
this.evenMoreDeep = `EvenMoreDeep : ${initWith}`; | |
return this; | |
}; | |
return EvenMoreDeep; | |
}; | |
// inherited props collector | |
const finalizeES5 = function (result = {}) { | |
let self = this; | |
const copyProps = () => { | |
Object.entries(self).forEach(([key, value] = entry) => { | |
if (!result.hasOwnProperty(key)) { | |
if (key !== 'constructor') { | |
result[key] = value; | |
} | |
} | |
}); | |
}; | |
copyProps(); | |
let proto = Object.getPrototypeOf(self); | |
while (proto) { | |
if (proto) { | |
self = proto; | |
copyProps(); | |
proto = Object.getPrototypeOf(self); | |
} else { | |
break; | |
} | |
}; | |
return result; | |
}; | |
// inherited props collector ancient style | |
var finalize = function() { | |
var result = {}; | |
// Important : nested props are also copied ! | |
for (var i in this) { | |
// should check if constructor is the same | |
// but for this example just get rid of it | |
// cause it is simply not the same | |
// for inherited instances | |
if (i !== 'constructor') { | |
result[i] = this[i]; | |
} | |
} | |
return result; | |
}; | |
// so we should create function | |
// which will return proper constructor | |
// of modificatorType constructors | |
// inherited from existent instance | |
// meaning existent instance is "this" keyword | |
const DataModificationConstructor = function (ModificatorType) { | |
const self = this; | |
if (!self || !self.constructor) { | |
throw new Error('Wrong Modification Pattern!'); | |
} | |
if (self instanceof ModificatorType) { | |
throw new Error('attempt to repeat the same inheritance'); | |
} | |
// console.log('\n\n\n', selfInstance === self, '\n\n\n'); // false | |
// console.log('\n\n\n', selfInstance instanceof self.constructor, '\n\n\n'); // true | |
const ModificatorTypeProto = ModificatorType.prototype; | |
const ModificatorTypeConstructor = ModificatorType.prototype.constructor; | |
var inheritedInstance; | |
var dataModificatorInstance; | |
const DataModificatorInheridedType = function () { | |
const UpperClosureType = function () { | |
const willBeModifiedInstance = this; | |
const ModificatorInheridedType = function (...args) { | |
// const prevCstr = this.constructor; | |
// make modification itself | |
// ModificatorTypeConstructor.call(this, ...args); | |
// Object.setPrototypeOf(DataModificatorInheridedType.prototype, ModificatorTypeProto); | |
// Object.setPrototypeOf(inheritedInstance, ModificatorTypeProto); | |
// Object.setPrototypeOf(dataModificatorInstance, ModificatorTypeProto); | |
ModificatorType.prototype.constructor.prototype = this; | |
// ModificatorType.prototype.constructor.prototype.constructor = ModificatorType; | |
inheritedInstance = new ModificatorType(...args); | |
// TODO : 3) should try to reorganize it | |
// leaving inheritedInstance.constructor.prototype untouched | |
Object.defineProperty(inheritedInstance.constructor.prototype, 'constructor', { | |
value : ModificatorType, | |
// TODO : !!! закомментировать и разобраться | |
writable : true | |
}); | |
Object.defineProperty(inheritedInstance.constructor.prototype.constructor.prototype.constructor, 'prototype', { | |
// might be the same as above | |
// Object.defineProperty(inheritedInstance.constructor.prototype.constructor, 'prototype', { | |
value : ModificatorInheridedType.prototype | |
}); | |
// inheritedInstance.constructor.prototype.constructor = ModificatorType; | |
// inheritedInstance.constructor.prototype.constructor.prototype.constructor.prototype = ModificatorInheridedType.prototype; | |
return inheritedInstance; | |
}; | |
ModificatorInheridedType.prototype = willBeModifiedInstance; | |
// ModificatorInheridedType.prototype.constructor = ModificatorInheridedType; | |
// the line upper is equal | |
// to the line below | |
// but, below example is not enumerable | |
// and we got rid of this constructor appear in log | |
// where "... yes ... this is a sorrow ..." | |
Object.defineProperty(ModificatorInheridedType.prototype, 'constructor', { | |
value : ModificatorInheridedType, | |
// TODO : !!! закомментировать и разобраться | |
writable : true | |
}); | |
Object.entries(ModificatorTypeProto).forEach(([key, value] = entry) => { | |
if (!ModificatorInheridedType.prototype.hasOwnProperty(key)) { | |
ModificatorInheridedType.prototype[key] = undefined; | |
ModificatorInheridedType.prototype[key] = ModificatorTypeProto[key]; | |
} | |
}); | |
return ModificatorInheridedType; | |
}; | |
UpperClosureType.prototype = this; | |
if (!ModificatorTypeProto.hasOwnProperty('desciption')) { | |
UpperClosureType.prototype.description = ModificatorType.prototype.constructor.name; | |
} | |
return new UpperClosureType(); | |
}; | |
DataModificatorInheridedType.prototype = self; | |
dataModificatorInstance = new DataModificatorInheridedType(); | |
// DataModificatorInheridedType.prototype = dataModificatorInstance; | |
// DataModificatorInheridedType.prototype.constructor = ModificatorType; | |
return dataModificatorInstance; | |
}; | |
console.log('\n\n: STARTING :\n\n'); | |
const UserType = createUserType(); | |
const UserTypeModification = | |
DataModificationConstructor.call(Object.create({}), UserType); | |
debugger; | |
const userInstance = new UserTypeModification({ | |
email: '[email protected]', | |
password: 123 | |
}); | |
console.log('1. By default userInstance.prototype is not referenced :', userInstance.prototype); | |
console.log('2. But constructor is, and points to : ', userInstance.constructor.name, | |
` : ${UserType.name === userInstance.constructor.name}`); | |
const userInstanedBefore = inspect(userInstance); | |
console.log('3. And userInstance value till this moment is :'); | |
console.log(userInstanedBefore); | |
var callsAmount = 0; | |
// if we will cast this line | |
// directly before calling | |
// const userWithoutPassword = new UserWithoutPasswordTypeModificator(); | |
// it will fail inheritance | |
// this cycle closure is unnecessary | |
// just demonstration it still works | |
const InstanceClosures = [1, 2, 3]; | |
const InstanceClosuresLength = InstanceClosures.length; | |
const punchlines = {}; | |
const printPunchlines = () => { | |
console.log('\n\n\n\n'); | |
console.log('****************************************************************************************************'); | |
console.log('\n'); | |
Object.values(punchlines).forEach(({ | |
start, | |
end | |
} = punchline) => { | |
console.log('\n\n'); | |
start(); | |
console.log(); | |
end(); | |
}); | |
console.log('\n\n\n'); | |
console.log('****************************************************************************************************'); | |
console.log('\n'); | |
}; | |
// here we make scoped instances | |
InstanceClosures | |
.map(function (num) { | |
// just for checking ;^) | |
// thought if we will create DataModificationConstructor | |
// in this scope, userWithoutPassword will inherit addition property | |
// userInstance.addition = num; | |
const UserWithoutPasswordType = createNewUserWithoutPasswordType(); | |
const UserWithoutPasswordTypeModificator | |
= DataModificationConstructor.call(userInstance, UserWithoutPasswordType); | |
const userWithoutPassword = new UserWithoutPasswordTypeModificator(); | |
// inherited from the same user instance | |
// and with absolutely the same inithal data | |
// but with different pointer to that data | |
const anotherUserWithoutPassword = new UserWithoutPasswordTypeModificator(); | |
const AdditionalModificatorType = createNewUserDataTypeExampleModType(); | |
const AdditionalModificatorTypeModificator | |
= DataModificationConstructor.call(anotherUserWithoutPassword, AdditionalModificatorType); | |
const userWithoutPasswordWithAdditionalModification = new AdditionalModificatorTypeModificator(num); | |
const AdditionalModificatorTypeNext = createNewUserDataTypeExampleModTypeNext(); | |
const AdditionalModificatorTypeModificatorNext | |
= DataModificationConstructor.call(userWithoutPasswordWithAdditionalModification, AdditionalModificatorTypeNext); | |
const userWithoutPasswordWithAdditionalModificationNext = new AdditionalModificatorTypeModificatorNext(num); | |
const MoreDeep = createMoreDeep(); | |
const MoreDeepTypeModificator | |
= DataModificationConstructor.call(userWithoutPasswordWithAdditionalModificationNext, MoreDeep); | |
const moreDeep = new MoreDeepTypeModificator(num); | |
const EvenMoreDeep = createEvenMoreDeep(); | |
const EvenMoreDeepTypeModificator | |
= DataModificationConstructor.call(moreDeep, EvenMoreDeep); | |
const evenMoreDeep = new EvenMoreDeepTypeModificator(num); | |
debugger; | |
const finMD = finalize.call(moreDeep); | |
const finEMD = finalize.call(evenMoreDeep); | |
debugger; | |
userWithoutPassword.sign = `userWithoutPassword.sign : ${num}`; | |
anotherUserWithoutPassword.sign = `anotherUserWithoutPassword.sign : ${num}`; | |
const inUserType = userWithoutPassword instanceof UserType; | |
const inUserWPType = userWithoutPassword instanceof UserWithoutPasswordType; | |
const inUserWPTypeModificator = userWithoutPassword instanceof UserWithoutPasswordTypeModificator; | |
const inBoth = inUserType && inUserWPType; | |
const result = { | |
num, | |
userInstance, | |
userWithoutPassword, | |
anotherUserWithoutPassword, | |
userWithoutPasswordWithAdditionalModification, | |
UserWithoutPasswordType, | |
UserWithoutPasswordTypeModificator, | |
inUserType, | |
inUserWPType, | |
inUserWPTypeModificator, | |
inBoth, | |
}; | |
punchlines[num] = { | |
start : () => { | |
console.log(`PUNCHLINE ::: START ::: ${num}`); | |
console.log('XXX : userWithoutPassword instanceof UserType : ', inUserType); | |
console.log('XXX : userWithoutPassword instanceof UserWithoutPasswordType : ', inUserWPType); | |
console.log('XXX : userWithoutPassword instanceof UserWithoutPasswordTypeModificator : ', inUserWPTypeModificator); | |
console.log('This tells us, that immediately after Instance Creation everything was : ', inBoth ? 'OK!' : 'FAILED!'); | |
console.log('YYY : userWithoutPasswordWithAdditionalModification instanceof UserType : ', | |
userWithoutPasswordWithAdditionalModification instanceof UserType); | |
console.log('YYY : userWithoutPasswordWithAdditionalModification instanceof UserWithoutPasswordType : ', | |
userWithoutPasswordWithAdditionalModification instanceof UserWithoutPasswordType); | |
console.log('YYY : userWithoutPasswordWithAdditionalModification instanceof AdditionalModificatorType : ', | |
userWithoutPasswordWithAdditionalModification instanceof AdditionalModificatorType); | |
console.log('YYY : userWithoutPasswordWithAdditionalModification instanceof AdditionalModificatorTypeModificator : ', | |
userWithoutPasswordWithAdditionalModification instanceof AdditionalModificatorTypeModificator); | |
console.log('YYY : userWithoutPasswordWithAdditionalModification.constructor : ', | |
userWithoutPasswordWithAdditionalModification.constructor.name); | |
} | |
}; | |
return result; | |
}) | |
.forEach(({ | |
num, | |
userInstance, | |
userWithoutPassword, | |
anotherUserWithoutPassword, | |
userWithoutPasswordWithAdditionalModification, | |
UserWithoutPasswordType, | |
UserWithoutPasswordTypeModificator, | |
inUserType, | |
inUserWPType, | |
inUserWPTypeModificator, | |
inBoth, | |
} = result) => { | |
// and here we check they are inherited properly | |
setTimeout(() => { | |
callsAmount++; | |
console.log(`\n\n\n: BOOM ${num} :\n\n`); | |
const stillInUserType = userWithoutPassword instanceof UserType; | |
const stillInUserWPType = userWithoutPassword instanceof UserWithoutPasswordType; | |
const stillInUserWPTypeModificator = userWithoutPassword instanceof UserWithoutPasswordTypeModificator; | |
punchlines[num].end = () => { | |
console.log(`PUNCHLINE ::: END ::: ${num}`, 'of', InstanceClosuresLength); | |
console.log('XXX : userWithoutPassword instanceof UserType : ', | |
stillInUserType, ' : expected : ', inUserType); | |
console.log('XXX : userWithoutPassword instanceof UserWithoutPasswordType : ', | |
stillInUserWPType, ' : expected : ', inUserWPType); | |
console.log('XXX : userWithoutPassword instanceof UserWithoutPasswordTypeModificator : ', | |
stillInUserWPTypeModificator, ' : expected : ', inUserWPTypeModificator); | |
}; | |
console.log('4. The prototype of userWithoutPassword instance is not referenced also :', userWithoutPassword.prototype); | |
const isReferenced = UserWithoutPasswordType.name === userWithoutPassword.constructor.name; | |
console.log('5. And the constructor still does, and points to : ', UserWithoutPasswordType.name, | |
` : ${isReferenced}`, isReferenced ? ': as expected' : ': not expected'); | |
console.log('\n'); | |
const userInstanedAfter = inspect(userInstance); | |
console.log('6.1 And userInstance is as before :', userInstanedAfter === userInstanedBefore ? 'equal ': 'not equal'); | |
console.log(userInstanedAfter); | |
console.log('\n'); | |
console.log('6.2 userInstance constructor still points to : ', userInstance.constructor.name, | |
` : ${UserType.name === userInstance.constructor.name}`); | |
console.log('\n\n: AND :\n\n'); | |
console.log('7.1 userWithoutPassword.email by reference to prototype is : ', userWithoutPassword.email); | |
console.log('7.2 userWithoutPassword.hasOwnProperty("email") is : ', userWithoutPassword.hasOwnProperty('email'), | |
userWithoutPassword.hasOwnProperty('email') ? ' : unexpected' : ' : as expected'); // false | |
console.log('7.3 userWithoutPassword.hasOwnProperty("password") is : ', userWithoutPassword.hasOwnProperty('password')); | |
console.log('7.4 userWithoutPassword.hasOwnProperty("constructor") is : ', userWithoutPassword.hasOwnProperty('constructor'), | |
userWithoutPassword.hasOwnProperty('constructor') ? ' : unexpected' : ' : as expected'); // false | |
console.log('7.5 userWithoutPassword.hasOwnProperty("description") is : ', userWithoutPassword.hasOwnProperty('description'), | |
userWithoutPassword.hasOwnProperty('description') ? ' : unexpected' : ' : as expected'); // false | |
console.log('\n: top :\n'); | |
console.log('8. userWithoutPassword.password is : ', userWithoutPassword.password, userWithoutPassword.password === undefined ? ' : as expedted' : ' : not expected'); | |
console.log('\n\n: CHECKING :\n\n'); | |
const userLogDataAncientWay = finalize.call(userInstance); | |
console.log( | |
'Logging via Ancient Way [ userInstance ]', | |
Object.keys(userLogDataAncientWay), | |
); | |
console.log(inspect(userLogDataAncientWay)); | |
const userLogDataNewWay = finalizeES5.call(userInstance); | |
console.log( | |
'Logging via modern ES Way [ userInstance ]', | |
Object.keys(userLogDataNewWay), | |
); | |
console.log(inspect(userLogDataNewWay)); | |
console.log('\n'); | |
const userWithoutPasswordLogDataAncientWay = finalize.call(userWithoutPassword); | |
console.log( | |
'Logging via Ancient Way [ userWithoutPassword ]', | |
Object.keys(userWithoutPasswordLogDataAncientWay), | |
); | |
console.log(inspect(userWithoutPasswordLogDataAncientWay)); | |
const userWithoutPasswordLogDataNewWay = finalizeES5.call(userWithoutPassword); | |
console.log( | |
'Logging via modern ES Way [ userWithoutPassword ]', | |
Object.keys(userWithoutPasswordLogDataNewWay), | |
); | |
console.log(inspect(userWithoutPasswordLogDataNewWay)); | |
console.log('\n'); | |
const anotherUserWithoutPasswordLogDataAncientWay = finalize.call(anotherUserWithoutPassword); | |
console.log( | |
'Logging via Ancient Way [ anotherUserWithoutPassword ]', | |
Object.keys(anotherUserWithoutPasswordLogDataAncientWay), | |
); | |
console.log(inspect(anotherUserWithoutPasswordLogDataAncientWay)); | |
const anotherUserWithoutPasswordLogDataNewWay = finalizeES5.call(anotherUserWithoutPassword); | |
console.log( | |
'Logging via modern ES Way [ anotherUserWithoutPassword ]', | |
Object.keys(anotherUserWithoutPasswordLogDataNewWay), | |
); | |
console.log(inspect(anotherUserWithoutPasswordLogDataNewWay)); | |
console.log('\n'); | |
const userWithoutPasswordWithAdditionalModificationLogData = | |
finalizeES5.call(userWithoutPasswordWithAdditionalModification); | |
console.log( | |
'Logging via modern ES Way [ userWithoutPasswordWithAdditionalModificationLogData ]', | |
Object.keys(userWithoutPasswordWithAdditionalModificationLogData), | |
); | |
console.log(inspect(userWithoutPasswordWithAdditionalModificationLogData)); | |
// console.log(userWithoutPasswordLogDataNewWay.hasOwnProperty('constructor')); | |
// console.log(userWithoutPassword.hasOwnProperty('constructor')); | |
console.log('\n\n'); | |
// Does SOLID still exist? | |
const comparator = (title, expected, received) => { | |
try { | |
deepStrictEqual(expected, received); | |
return `${title} : passed`; | |
} catch (error) { | |
return `${title} : failed`; | |
} | |
}; | |
console.log( | |
comparator( | |
'Comparator Equality Keys', | |
Object.keys(userWithoutPasswordLogDataAncientWay), | |
Object.keys(userWithoutPasswordLogDataNewWay) | |
) | |
); | |
console.log( | |
comparator( | |
'Comparator Equality Props', | |
inspect(userWithoutPasswordLogDataAncientWay), | |
inspect(userWithoutPasswordLogDataNewWay) | |
) | |
); | |
console.log( | |
comparator( | |
'must be still the same, unchanged', | |
UserType.prototype.description, | |
userTypePrototypeDesc | |
), ': UserType.prototype.description :', | |
UserType.prototype.description === | |
userTypePrototypeDesc | |
); | |
console.log( | |
comparator( | |
'must be still the same, unchanged', | |
UserWithoutPasswordType.prototype.description, | |
UserWithoutPasswordTypePrototypeDesc | |
), ': UserWithoutPasswordType.prototype.desciption :', | |
UserWithoutPasswordType.prototype.description === | |
UserWithoutPasswordTypePrototypeDesc | |
); | |
console.log('userInstance instanceof UserType : ', userInstance instanceof UserType); | |
console.log('userInstance ! instanceof UserWithoutPasswordType : ', !(userInstance instanceof UserWithoutPasswordType)); | |
console.log('\n'); | |
console.log(`PUNCHLINE ::: REPORT ${num}`); | |
console.log('XXX : userWithoutPassword instanceof UserType : ', | |
userWithoutPassword instanceof UserType, 'expected', inUserType); | |
console.log('XXX : userWithoutPassword instanceof UserWithoutPasswordType : ', | |
userWithoutPassword instanceof UserWithoutPasswordType, 'expected', inUserWPType); | |
console.log('XXX : userWithoutPassword instanceof UserWithoutPasswordTypeModificator : ', | |
stillInUserWPTypeModificator, ' : expected : ', inUserWPTypeModificator); | |
console.log('\n'); | |
console.log('UserType ! instanceof UserWithoutPasswordType : ', !(UserType instanceof UserWithoutPasswordType)); | |
console.log('UserType unchanged : ', UserType === userInstance.constructor); | |
console.log('UserType.prototype', UserType.prototype); | |
console.log('UserType.constructor', UserType.constructor); | |
console.log('UserType.constructor.prototype', UserType.constructor.prototype); | |
console.log(); | |
console.log('UserWithoutPasswordType ! instanceof UserType : ', !(UserWithoutPasswordType instanceof UserType)); | |
console.log('UserWithoutPasswordType unchanged : ', UserWithoutPasswordType === userWithoutPassword.constructor); | |
console.log('\nUserWithoutPasswordType.prototype', UserWithoutPasswordType.prototype); | |
console.log(`\n\t... yes ... this is a sorrow ... | |
look for | |
Object.defineProperty(ModificatorInheridedType.prototype, 'constructor' | |
upper of this code, and re-comment lines\n`); | |
console.log('UserWithoutPasswordType.constructor', UserWithoutPasswordType.constructor); | |
console.log('UserWithoutPasswordType.constructor.prototype', UserWithoutPasswordType.constructor.prototype); | |
console.log('\n\n\t... thought now we have the following : \n'); | |
console.log('userWithoutPassword.constructor : ', userWithoutPassword.constructor.name); | |
console.log('userInstance.constructor : ', userInstance.constructor.name); | |
if (callsAmount === InstanceClosuresLength) { | |
printPunchlines(); | |
} | |
}, 50); | |
}); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// Transformation Card PoC | |
const assert = require('assert'); | |
const { strictEqual, deepStrictEqual } = assert; | |
const util = require('util'); | |
const inspect = (value) => { | |
return util.inspect(value, { | |
colors : true, | |
compact : false | |
}) | |
}; | |
const UserType = function ({ email, password } = userData) { | |
this.email = email; | |
this.password = password; | |
return this; | |
}; | |
UserType.prototype.description = 'User ETL~DFD'; | |
UserType.prototype.email = ''; | |
UserType.prototype.password = ''; | |
// starting | |
const user = new UserType({ | |
email: '[email protected]', | |
password: 123 | |
}); | |
// const user321 = new UserType({ | |
// email: '[email protected]', | |
// password: 321 | |
// }); | |
UserType.WithoutPassword = function () { | |
// now this referes to new empty object | |
// which we should fill | |
UserType; | |
UserType.WithoutPassword; | |
user; | |
// const formerUser = this.constructor.prototype.constructor.prototype; | |
this.password = undefined; | |
debugger; | |
this.constructor.prototype.constructor = UserType.WithoutPassword; | |
this.constructor.prototype.constructor.prototype.constructor = UserType; | |
debugger; | |
// this.constructor.prototype.constructor = UserType.WithoutPassword; | |
// return userWP; | |
}; | |
UserType.WithoutPassword.prototype = user; | |
// so now UserType.WithoutPassword.prototype is user | |
// this means UserType.WithoutPassword.prototype.constructor is now UserType; | |
// and also means UserType.WithoutPassword.prototype.constructor.prototype is UserType.prototype; | |
// console.log(UserType.WithoutPassword.prototype.constructor.prototype.constructor === UserType); | |
// mooving it deeper | |
// UserType.WithoutPassword | |
// .prototype.constructor | |
// .prototype.constructor | |
// .prototype.constructor.prototype = | |
// UserType.WithoutPassword.prototype; | |
const userWP = new UserType.WithoutPassword(); | |
console.log('user instanceof UserType', user instanceof UserType); | |
console.log('userWP instanceof UserType', userWP instanceof UserType); | |
console.log('userWP instanceof UserType.WithoutPassword', userWP instanceof UserType.WithoutPassword); | |
console.log('user.constructor.name :', user.constructor.name); | |
console.log('userWP.constructor.name :', userWP.constructor.name); | |
user.password = 321; | |
console.log('UserType.prototype', inspect(UserType.prototype)); | |
console.log('UserType.WithoutPassword.prototype', inspect(UserType.WithoutPassword.prototype)); | |
debugger; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment