Last active
February 7, 2018 04:49
-
-
Save jnvm/56f8b8eb05f615bfea1512034017446b to your computer and use it in GitHub Desktop.
privatizer.js
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 | |
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