森建 (2016-01-19T15:24:02.000Z)
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());
```
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());
```