Last active
December 29, 2015 19:28
-
-
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
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
node_modules/ |
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
#!/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); |
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
{ | |
"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": {} | |
} |
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
#!/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