Last active
February 7, 2018 04:51
-
-
Save jnvm/f06308f537dd129d5f8253615aac947c to your computer and use it in GitHub Desktop.
a privatizer
This file contains 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
/* | |
given goals: | |
https://github.com/tc39/proposal-class-fields/blob/master/PRIVATE_SYNTAX_FAQ.md#why-is-encapsulation-a-goal-of-this-proposal | |
& given example: | |
https://github.com/tc39/proposal-class-fields/blob/master/PRIVATE_SYNTAX_FAQ.md#how-can-you-provide-hidden-but-not-encapsulated-properties-using-symbols | |
Hidden & encapsulated values can be shared with same instances via WeakMap & Proxies | |
Undesirable access via callbacks passed in & whatnot just need to be defended against. | |
One could imagine wanting to allow callbacks read access to privates but not write, doable w/a proxy & setup condition. | |
*/ | |
function privatizer(){ | |
const store = new WeakMap | |
return { | |
privates:{ | |
get:p=>store.get(p), | |
set(target,nu){ | |
Object.keys(nu).forEach(k=>{ | |
if(nu[k].constructor===Function.constructor && nu[k].bind){ | |
nu[k]=nu[k].bind({}) | |
} | |
}) | |
return store.set(target,nu) | |
} | |
} | |
} | |
} | |
const Person = (function() { | |
let ids = 0; | |
const {privates} = privatizer() | |
return class Person { | |
constructor(name,greeting=(other)=>`howdy ${other}`) { | |
this.name = name; | |
privates.set(this,{id: ids++,greeting}) | |
} | |
sayMyId(){ console.log(`${this.name}'s id is: ${privates.get(this).id}`) } | |
equals(otherPerson) { | |
return privates.get(this).id === privates.get(otherPerson).id | |
} | |
greet(other){ | |
console.log(`${this.name}: ${privates.get(this).greeting(other.name)}`) | |
} | |
} | |
})(); | |
let alice = new Person('Alice',function(name){this.id=9;return `hark to ${name}!!`});//oh no, attempts to change privates via this! | |
let bob = new Person('Bob',function(name){this.id=9;return `salutations to ${name}!`}); | |
let Imposter=Person.bind(alice)//? | |
let dillon = new Imposter('Dillon') | |
alice.sayMyId() //Alice's id is: 0 | |
bob.sayMyId() //Bob's id is: 1 | |
dillon.sayMyId() //Dillon's id is: 2 | |
alice.greet(bob) //Alice: hark to Bob!! | |
bob.greet(alice) //Bob: salutations to Alice from Bob! | |
bob.greet(bob) //Bob: salutations to Bob from Bob! | |
dillon.greet(alice)//Dillon: howdy Alice | |
//but it has no effect | |
alice.sayMyId() //Alice's id is: 0 | |
bob.sayMyId() //Bob's id is: 1 | |
dillon.sayMyId() //Dillon's id is: 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment