Skip to content

Instantly share code, notes, and snippets.

@brenolf
Last active August 29, 2015 14:20
Show Gist options
  • Save brenolf/23d0aebb396621a07d06 to your computer and use it in GitHub Desktop.
Save brenolf/23d0aebb396621a07d06 to your computer and use it in GitHub Desktop.
Private attributes and attribute accessors using decorators
import * from './privatize.js';
let token = Symbol(); // this is a class secret!
export class Babel {
@attr_accessor // <- create getters and setters
@privatize(token) // <- private attributes turns into functions `fun (token, ...args)`
lang;
@attr_accessor
@privatize(token)
country;
@privatize(token)
phrase;
constructor () {
this.phrase(token, ' speaks ');
}
public_method () {
this.private_method(token);
}
@privatize(token)
private_method () {
console.log(`${this.country}${this.phrase(token)}${this.lang}`);
}
}
export function privatize (TOKEN) {
return function (t, n, d) {
let pass = function (value) {
if (value !== TOKEN)
throw new Error(`"${n}" is private method`);
}
var original = d.value;
// variable
if ('initializer' in d) {
delete d.initializer;
let key = Symbol();
d.value = function (token, value) {
pass(token);
if (value === undefined)
return this[key];
else
this[key] = value;
}
return;
}
// method
d.value = function () {
pass(arguments[0]);
this::original(arguments);
}
}
}
export function attr_accessor (t, n, d) {
delete d.initializer;
delete d.value;
let key = Symbol();
d.get = function () {
return this[key];
}
d.set = function (value) {
this[key] = value;
}
}
export function attr_reader (t, n, d) {
delete d.initializer;
delete d.value;
let key = Symbol();
d.get = function () {
return this[key];
}
}
export function attr_writer (t, n, d) {
delete d.initializer;
delete d.value;
let key = Symbol();
d.set = function (value) {
this[key] = value;
}
}
import {Babel} from './babel.js';
var b = new Babel();
b.country = 'brazil';
b.lang = 'portuguese'
console.log(b.public_method());
try {
b.private_method();
} catch (e) {
console.log(e.message); // "private_method" is private method
}
try {
b.phrase = 'hey';
} catch (e) {
console.log(e.message); // Cannot assign to read only property 'phrase' of [object Object]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment