Lastly, an even better optimization: I'll conclude this by showing how to be used even more specifically like the class I'm trying to implement, Here's a version where the object itself is the handler, along with it's target! Therefore returning *new Proxy(this, this)*; as the only line of the constructor!
class MyClass { data = {}; constructor() { return new Proxy(this, this); } get(target, prop) { prop = prop.toString(); console.log(`Getting property: ${prop}`); if(prop==="toString"){ return this.toString.bind(target); } if(prop==='valueOf'){ return this.valueOf.bind(target); } if(prop==="Symbol(Symbol.iterator)"){ return this[Symbol.iterator].bind(target); } return this.data[prop]; } set(target, prop, value) { console.log(`Setting property: ${prop.toString()} to ${value}`); this.data[prop] = value; return true; } deleteProperty(target, prop) { console.log(`Deleting property: ${prop.toString()}`); delete this.data[prop.toString()]; return true; } has(target, prop) { console.log(`Checking property presence: ${prop.toString()}`); return prop in this.data; } valueOf() { return 'running valueOf: ' + JSON.stringify(this.data); } toString() { return 'running tostring:' + JSON.stringify(this.data); } *[Symbol.iterator]() { for (const key in this.data) { console.log('called iterator!'); yield [key, this.data[key]]; } } } Hope sharing this will help someone! :D Félix On Friday, August 4, 2023 at 9:55:32 PM UTC-4 Félix wrote: > Oops: corrected the typo in the example! > class MyClass { > data = {}; > > constructor() { > return new Proxy(this, { > get(target, prop) { > prop = prop.toString(); > console.log(`Getting property: ${prop}`); > if(prop==="toString"){ > return target.toString.bind(target); > } > if(prop==='valueOf'){ > return target.valueOf.bind(target); > } > if(prop==="Symbol(Symbol.iterator)"){ > return target[Symbol.iterator].bind(target); > } > return target.data[prop]; > }, > set(target, prop, value) { > console.log(`Setting property: ${prop.toString()} to ${value}`); > target.data[prop] = value; > return true; > }, > deleteProperty(target, prop) { > console.log(`Deleting property: ${prop.toString()}`); > delete target.data[prop.toString()]; > return true; > }, > has(target, prop) { > console.log(`Checking property presence: ${prop.toString()}`); > return prop in target.data; > }, > }); > } > > valueOf() { > return 'running valueOf: ' + JSON.stringify(this.data); > } > toString() { > return 'running tostring:' + JSON.stringify(this.data); > } > > *[Symbol.iterator]() { > for (const key in this.data) { > console.log('called iterator!'); > yield [key, this.data[key]]; > } > } > > } > > const obj = new MyClass(); > obj['key'] = 'value'; // Setting property: key to value > console.log("testing setting and getting 'key'"); > console.log(obj['key']); // Getting property: key, value > delete obj['key']; // Deleting property: key > console.log("deleted, should be false: ") > console.log('key' in obj); // Checking property presence: key, false > > console.log("testing toString ") > obj['key3'] = 'value1'; > obj['key4'] = 'value2'; > console.log(obj.toString()); // {"key1":"value1","key2":"value2"} > > console.log("testing Symbol.iterator"); > for (const [key, value] of obj) { > console.log(`${key}: ${value}`); > } > On Friday, August 4, 2023 at 9:53:24 PM UTC-4 Félix wrote: > >> Dunder methods being (unexhaustive list) : *__contains__, __delitem__, >> __getitem__, __setitem__, __iter__ and __repr__* in my case. >> >> Using javascript little-known 'Proxy object', and passing itself as the >> target, it's possible to implement the equivalent of Leo's >> SqlitePickleShare class! >> >> *simple proof-of-concept below where it just mimics a dummy dict. >> Customize as needed for other behaviors!* >> >> Félix 🚀😊 >> >> class MyClass { >> data = {}; >> >> constructor() { >> return new Proxy(this, { >> get(target, prop) { >> prop = prop.toString(); >> console.log(`Getting property: ${prop}`); >> if(prop==="toString"){ >> return target.toString.bind(target); >> } >> if(prop==='valueOf'){ >> return target.toString.bind(target); >> } >> if(prop==="Symbol(Symbol.iterator)"){ >> return target[Symbol.iterator].bind(target); >> } >> return target.data[prop]; >> }, >> set(target, prop, value) { >> console.log(`Setting property: ${prop.toString()} to ${value}`); >> target.data[prop] = value; >> return true; >> }, >> deleteProperty(target, prop) { >> console.log(`Deleting property: ${prop.toString()}`); >> delete target.data[prop.toString()]; >> return true; >> }, >> has(target, prop) { >> console.log(`Checking property presence: ${prop.toString()}`); >> return prop in target.data; >> }, >> }); >> } >> >> valueOf() { >> return 'running valueOf: ' + JSON.stringify(this.data); >> } >> toString() { >> return 'running tostring:' + JSON.stringify(this.data); >> } >> >> *[Symbol.iterator]() { >> for (const key in this.data) { >> console.log('called iterator!'); >> yield [key, this.data[key]]; >> } >> } >> >> } >> >> const obj = new MyClass(); >> obj['key'] = 'value'; // Setting property: key to value >> console.log("testing setting and getting 'key'"); >> console.log(obj['key']); // Getting property: key, value >> delete obj['key']; // Deleting property: key >> console.log("deleted, should be false: ") >> console.log('key' in obj); // Checking property presence: key, false >> >> console.log("testing toString ") >> obj['key3'] = 'value1'; >> obj['key4'] = 'value2'; >> console.log(obj.toString()); // {"key1":"value1","key2":"value2"} >> >> console.log("testing Symbol.iterator"); >> for (const [key, value] of obj) { >> console.log(`${key}: ${value}`); >> } >> > -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/leo-editor/98716f83-50f4-419d-97c7-ae6a27a4f872n%40googlegroups.com.