Skip to content

Instantly share code, notes, and snippets.

@ne-sachirou
Last active December 29, 2015 19:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ne-sachirou/f2a25a3c983b591c2bf5 to your computer and use it in GitHub Desktop.
Save ne-sachirou/f2a25a3c983b591c2bf5 to your computer and use it in GitHub Desktop.
private/protected/static of JavaScript class http://c4se.hatenablog.com/entry/2015/12/29/050124
node_modules/
#!/usr/bin/env babel-node
'use strict';
import assert from 'assert';
import uuid from 'node-uuid';
var Momonga = (() => {
function privateStaticHello() {
assert(!(this instanceof Momonga));
return 'private static hello';
}
function privateHello() {
assert(this instanceof Momonga);
return `private hello ${this.v}`;
}
var privateStore = new WeakMap();
class Momonga {
constructor(v) {
this.v = v;
privateStore.set(this, {privateHelloV: this.v});
}
publicHello() {
assert(this instanceof Momonga);
return `public hello ${this.v}`;
}
assert(v) {
// private static
assert.strictEqual(privateStaticHello(), `private static hello`);
// private
assert.strictEqual(privateHello.bind(this)(), `private hello ${v}`);
assert.strictEqual(privateHello.call(this), `private hello ${v}`);
assert.strictEqual(privateStore.get(this).privateHelloV, v);
}
}
Momonga.publicStaticHello = function () {
assert(!(this instanceof Momonga));
return 'public static hello';
};
return Momonga;
})();
var Frog = (() => {
function privateStaticCrow() {
assert(!(this instanceof Frog));
return 'private static crow';
}
function privateCrow() {
assert(this instanceof Frog);
return `private crow ${this.v}`;
}
var privateStore = new WeakMap();
class Frog extends Momonga {
constructor(v) {
super(v);
privateStore.set(this, {privateCrowV: this.v});
}
publicCrow() {
assert(this instanceof Frog);
return `public crow ${this.v}`;
}
_setProtetedProp(_id, k, v) {
if (super._getProtetedProps(_id).hasOwnProperty(k)) {
return super._setProtetedProp(_id, k, v);
}
var props = privateStore.get(this);
props[_id][k] = v;
privateStore.set(this, props);
}
assert(v) {
// private static
assert.strictEqual(privateStaticCrow(), `private static crow`);
assert.throws(() => { privateStaticHello }, ReferenceError);
// private
assert.strictEqual(privateCrow.bind(this)(), `private crow ${v}`);
assert.throws(() => { privateHello }, ReferenceError);
assert.strictEqual(privateStore.get(this).privateCrowV, v);
assert.strictEqual(privateStore.get(this).privateHelloV, void 0);
}
}
Frog.publicStaticCrow = function () {
assert(!(this instanceof Frog));
return 'public static crow';
};
return Frog;
})();
// public static
assert.strictEqual(Momonga.publicStaticHello(), 'public static hello');
// public
assert.strictEqual((new Momonga(2)).publicHello(), 'public hello 2');
assert.strictEqual((new Momonga(2)).v, 2);
// private static, private
assert.throws(() => { privateStaticHello }, ReferenceError);
assert.throws(() => { privateHello }, ReferenceError);
new Momonga(2).assert(2);
// public static
assert.strictEqual(Frog.publicStaticCrow(), 'public static crow');
assert.strictEqual(Frog.publicStaticHello(), 'public static hello');
// public
assert.strictEqual((new Frog(2)).publicCrow(), 'public crow 2');
assert.strictEqual((new Frog(2)).publicHello(), 'public hello 2');
assert.strictEqual((new Frog(2)).v, 2);
// private static, private
assert.throws(() => { privateStaticCrow }, ReferenceError);
assert.throws(() => { privateCrow }, ReferenceError);
new Frog(2).assert(2);
{
"name": "private-protected-js",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "babel-node index.js && babel-node protected.js"
},
"author": "ne_Sachirou <utakata.c4se@gmail.com>",
"license": "CC 0",
"babel": {
"presets": [
"es2015",
"stage-3"
]
},
"dependencies": {
"babel-preset-es2015": "^6.3.13",
"babel-preset-stage-3": "^6.3.13",
"node-uuid": "^1.4.7"
},
"devDependencies": {}
}
#!/usr/bin/env babel-node
'use strict';
import assert from 'assert';
import uuid from 'node-uuid';
{
let privateStore = new WeakMap();
let protectedStore = new WeakMap();
var Momonga = class Momonga {
constructor(v, _id) {
_id = _id || uuid.v4();
this.v = v;
privateStore.set(this, {_id: _id});
protectedStore.set(this, {});
Momonga.prototype._setProtetedProp.call(this, _id, 'protectedHelloV', `protected hello ${v}`);
}
_hasProtectedProp(_id, k) {
if (privateStore.get(this)._id !== _id) {
throw new Error("protected props can't access publicly.");
}
return protectedStore.get(this).hasOwnProperty(k);
}
_getProtectedProp(_id, k) {
if (privateStore.get(this)._id !== _id) {
throw new Error("protected props can't access publicly.");
}
return protectedStore.get(this)[k];
}
_setProtetedProp(_id, k, v) {
if (privateStore.get(this)._id !== _id) {
throw new Error("protected props can't access publicly.");
}
protectedStore.get(this)[k] = v;
}
protectedHello(_id) {
if (privateStore.get(this)._id !== _id) {
throw new Error("protected props can't access publicly.");
}
return `protected hello ${this.v}`;
}
assert(v) {
var _id = privateStore.get(this)._id;
assert.strictEqual(this.protectedHello(_id), `protected hello ${v}`);
assert.strictEqual(this._getProtectedProp(_id, 'protectedHelloV'), `protected hello ${v}`);
this._setProtetedProp(_id, 'k', v);
assert.strictEqual(this._getProtectedProp(_id, 'k'), v);
}
}
}
{
let privateStore = new WeakMap();
let protectedStore = new WeakMap();
var Frog = class Frog extends Momonga {
constructor(v, _id) {
_id = _id || uuid.v4();
super(v, _id);
privateStore.set(this, {_id: _id});
protectedStore.set(this, {});
Frog.prototype._setProtetedProp.call(this, _id, 'protectedCrowV', `protected crow ${v}`);
}
_hasProtectedProp(_id, k) {
var _thisId = privateStore.get(this)._id;
if (_thisId !== _id) {
throw new Error("protected props can't access publicly.");
}
return protectedStore.get(this).hasOwnProperty(k) || super._hasProtectedProp(_thisId, k);
}
_getProtectedProp(_id, k) {
var _thisId = privateStore.get(this)._id;
if (_thisId !== _id) {
throw new Error("protected props can't access publicly.");
}
return protectedStore.get(this)[k] || super._getProtectedProp(_thisId, k);
}
_setProtetedProp(_id, k, v) {
var _thisId = privateStore.get(this)._id;
if (_thisId !== _id) {
throw new Error("protected props can't access publicly.");
}
if (super._hasProtectedProp(_thisId, k)) {
return super._setProtetedProp(_thisId, k);
}
protectedStore.get(this)[k] = v;
}
protectedCrow(_id) {
if (privateStore.get(this)._id !== _id) {
throw new Error("protected props can't access publicly.");
}
return `protected crow ${this.v}`;
}
assert(v) {
var _id = privateStore.get(this)._id;
assert.strictEqual(this.protectedCrow(_id), `protected crow ${v}`);
assert.strictEqual(this.protectedHello(_id), `protected hello ${v}`);
assert.strictEqual(this._getProtectedProp(_id, 'protectedCrowV'), `protected crow ${v}`);
assert.strictEqual(this._getProtectedProp(_id, 'protectedHelloV'), `protected hello ${v}`);
this._setProtetedProp(_id, 'k', v);
assert.strictEqual(this._getProtectedProp(_id, 'k'), v);
}
}
}
new Momonga(2).assert(2);
assert.throws(() => { new Momonga(2).protectedHello() }, Error, "protected props can't access publicly.");
assert.strictEqual(new Momonga(2, 42)._getProtectedProp(42, 'protectedHelloV'), 'protected hello 2');
new Frog(2).assert(2);
assert.throws(() => { new Frog(2).protectedCrow() }, Error, "protected props can't access publicly.");
assert.throws(() => { new Frog(2).protectedHello() }, Error, "protected props can't access publicly.");
assert.strictEqual(new Frog(2, 42)._getProtectedProp(42, 'protectedCrowV'), 'protected crow 2');
assert.strictEqual(new Frog(2, 42)._getProtectedProp(42, 'protectedHelloV'), 'protected hello 2');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment