moriken at kimamass.com (2016-01-19T15:26:42.983Z)
I make it!
```js
"use strict";
// utility
function createProtectedStorage() {
const wm = new WeakMap();
return (self, protectedClass) => {
const map = wm.get(self);
if(protectedClass == null) {
if(map) {
return map;
} else {
const ret = Object.create(null);
wm.set(self, ret);
return ret;
}
}
const p = new protectedClass(self);
if(map) {
for(let key of Object.getOwnPropertyNames(map)) {
const descriptor = Object.getOwnPropertyDescriptor(map, key);
Object.defineProperty(p, key, descriptor);
}
}
wm.set(self, p);
return p;
}
}
const _ = createProtectedStorage();
class Protected_A {
constructor(publicThis) {
this.publicThis = publicThis;
}
getName() {
return `${this.publicThis.name} ${this.lastName}`;
}
}
class A {
constructor(name, lastName) {
// protected this
if(new.target === A) {
_(this, Protected_A);
}
// public property
this.name = name;
// protected property
Object.defineProperty(_(this), "lastName", {
enumerable: false,
configurable: false,
writable: false,
value: lastName
});
}
callGetName() {
// call protected method
return _(this).getName();
}
}
// extends
class Protected_B extends Protected_A {
constructor(publicThis) {
super(publicThis);
}
getAge() {
return this.age;
}
}
class B extends A {
constructor(name, lastName, age) {
super(name, lastName);
// protected this
if(new.target === B) _(this, Protected_B);
// protected property
_(this).age = age;
}
callGetAge() {
return _(this).getAge();
}
// added
getData() {
return {
name: _(this).getName(), // Protected_A
age: _(this).getAge()
}
}
getLastNameDescriptor() {
return Object.getOwnPropertyDescriptor(_(this), "lastName");
}
getAgeDescriptor() {
return Object.getOwnPropertyDescriptor(_(this), "age");
}
}
// test
const b = new B("foo", "bar", 18);
// "foo bar"
console.log(b.callGetName());
// 18
console.log(b.callGetAge());
// { "name": "foo bar", "age": 18 }
console.log(b.getData());
// { "value": "bar", "writable": false, "enumerable": false, "configurable": false }
console.log(b.getLastNameDescriptor());
// { "value": 18, "writable": true, "enumerable": true, "configurable": true }
console.log(b.getAgeDescriptor());
```
I make it! ```js "use strict"; // utility function createProtectedStorage() { const wm = new WeakMap(); return (self, protectedClass) => { const map = wm.get(self); if(protectedClass == null) { if(map) { return map; } else { const ret = Object.create(null); wm.set(self, ret); return ret; } } const p = new protectedClass(self); if(map) { for(let key of Object.getOwnPropertyNames(map)) { const descriptor = Object.getOwnPropertyDescriptor(map, key); Object.defineProperty(p, key, descriptor); } } wm.set(self, p); return p; } } const _ = createProtectedStorage(); class Protected_A { constructor(publicThis) { this.publicThis = publicThis; } getName() { return `${this.publicThis.name} ${this.lastName}`; } } class A { constructor(name, lastName) { // protected this if(new.target === A) { _(this, Protected_A); } // public property this.name = name; // protected property Object.defineProperty(_(this), "lastName", { enumerable: false, configurable: false, writable: false, value: lastName }); } callGetName() { // call protected method return _(this).getName(); } } // extends class Protected_B extends Protected_A { constructor(publicThis) { super(publicThis); } getAge() { return this.age; } } class B extends A { constructor(name, lastName, age) { super(name, lastName); // protected this if(new.target === B) _(this, Protected_B); // protected property _(this).age = age; } callGetAge() { return _(this).getAge(); } // added getData() { return { name: _(this).getName(), // Protected_A age: _(this).getAge() } } getLastNameDescriptor() { return Object.getOwnPropertyDescriptor(_(this), "lastName"); } getAgeDescriptor() { return Object.getOwnPropertyDescriptor(_(this), "age"); } } // test const b = new B("foo", "bar", 18); // "foo bar" console.log(b.callGetName()); // 18 console.log(b.callGetAge()); // { "name": "foo bar", "age": 18 } console.log(b.getData()); // { "value": "bar", "writable": false, "enumerable": false, "configurable": false } console.log(b.getLastNameDescriptor()); // { "value": 18, "writable": true, "enumerable": true, "configurable": true } console.log(b.getAgeDescriptor()); ```