Last active
October 18, 2021 17:53
-
-
Save wentout/dcc50aa3a1e54e484fe29ba16adb5a61 to your computer and use it in GitHub Desktop.
The Ring from Proxies
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'; | |
const a = { a: 1 }; | |
const b = { b: 2 }; | |
const c = { c: 3 }; | |
const d = { d: 4 }; | |
const e = { e: 5 }; | |
const proxify = (a) => { | |
const p = new Proxy(a, { | |
get(target, prop, receiver) { | |
debugger; | |
if (target[prop]) { | |
return target[prop]; | |
} | |
return Reflect.get(receiver, proto); | |
}, | |
setPrototypeOf(into, value) { | |
Object.setPrototypeOf(a, value); | |
return true; | |
} | |
}); | |
return p; | |
}; | |
const ring = (...args) => { | |
const initial = proxify(args[0]); | |
let current = initial; | |
args.slice(1).forEach(arg => { | |
const p = proxify(arg); | |
Object.setPrototypeOf(current, p); | |
current = p; | |
}, current); | |
Object.setPrototypeOf(current, initial); | |
return initial; | |
}; | |
debugger; | |
const theRing = ring(a, b, c, d, e); | |
debugger; | |
console.log(theRing.a === 1); | |
console.log(theRing.b === 2); | |
console.log(theRing.c === 3); | |
console.log(theRing.d === 4); | |
console.log(theRing.e === 5); | |
debugger; | |
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'; | |
class A { a = 1 }; | |
class B { b = 2 }; | |
class C { c = 3 }; | |
class D { d = 4 }; | |
class E { e = 5 }; | |
const a = new A; | |
const b = new B; | |
const c = new C; | |
const d = new D; | |
const e = new E; | |
debugger; | |
// const commonProps = Object.getOwnPropertyDescriptors(Object.prototype); | |
const commonProps = Object.getOwnPropertyDescriptors(Object.getPrototypeOf({})); | |
const proxify = function (initial) { | |
const props = Object.getOwnPropertyDescriptors(initial); | |
const handler = { | |
get(target, prop, receiver) { | |
if (prop === Symbol.toPrimitive) { | |
// node.js inspector needs this | |
// debugger; | |
proxify.started = undefined; | |
return function () { | |
return 'the ring'; | |
}; | |
} | |
// any of other symbols are... | |
// emm... | |
// how for example Symbol nodejs.utils.custom??? | |
if (typeof prop === 'symbol') { | |
debugger; | |
return undefined; | |
} | |
if (target[prop]) { | |
return target[prop]; | |
} | |
debugger; | |
return Reflect.get(receiver, prop); | |
}, | |
setPrototypeOf(into, value) { | |
// Object.setPrototypeOf(into, value); | |
// https://262.ecma-international.org/7.0/#sec-immutable-prototype-exotic-objects | |
// https://github.com/tc39/ecma262/issues/272 | |
// const proto = Object.getPrototypeOf(initial); | |
Object.setPrototypeOf(initial, value); | |
return true; | |
}, | |
ownKeys(target) { | |
const keys = Reflect.ownKeys(target); | |
debugger; | |
return keys; | |
}, | |
getOwnPropertyDescriptor(target, prop) { | |
// if (commonProps[prop]) { | |
// const answer = commonProps[prop]; | |
// const result = Object.assign({}, answer); | |
// return result; | |
// } | |
if (prop === 'constructor') { | |
return { | |
configurable: false | |
}; | |
} | |
const answer = props[prop]; | |
debugger; | |
return answer; | |
} | |
}; | |
const p = new Proxy(initial, handler); | |
return p; | |
}; | |
const ring = (...args) => { | |
const initial = proxify(args[0]); | |
let current = initial; | |
args.slice(1).forEach(arg => { | |
const p = proxify(arg); | |
Object.setPrototypeOf(current, p); | |
current = p; | |
}, current); | |
Object.setPrototypeOf(current, initial); | |
return initial; | |
}; | |
debugger; | |
const loop = [a, b, c, d, e]; | |
const theRing = ring(...loop); | |
debugger; | |
console.log(theRing.a === 1); | |
console.log(theRing.b === 2); | |
console.log(theRing.c === 3); | |
console.log(theRing.d === 4); | |
console.log(theRing.e === 5); | |
debugger; | |
loop.forEach(obj => { | |
debugger; | |
console.log(Object.getOwnPropertyDescriptors(obj)); | |
console.log(obj.a === 1); | |
console.log(obj.b === 2); | |
console.log(obj.c === 3); | |
console.log(obj.d === 4); | |
console.log(obj.e === 5); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment