Symbols
を利用します。例えば Person
クラスで「名前」「年齢」を private にしたい場合は次のようにします。
const propName = Symbol();
const propAge = Symbol();
/**
* Person class
*/
class Person {
/**
* @constructor
* @param {string} name
* @param {number} age
*/
constructor(name, age) {
this[propName] = name;
this[propAge] = age;
}
}
export default Person;
変数
propName
およびpropAage
は一意であり、他の方法で同値のものを生成できず、アクセスできるのはこのファイル内のみです。
この例では、インスタンス生成時に「名前」「年齢」をセットした後は、
import Person from './person.es6';
const person = new Person('Yamada', 45);
「名前」「年齢」にアクセスすることはできません。
「名前」「年齢」を Person
クラス内のメソッドのみで利用する場合はこれでいいのですが、外部から参照だけしたい場合は Getter を用意すればいいです。
const propName = Symbol();
const propAge = Symbol();
/**
* Person class
*/
class Person {
/**
* @constructor
* @param {string} name
* @param {number} age
*/
constructor(name, age) {
this[propName] = name;
this[propAge] = age;
}
/**
* @returns {string}
*/
get name() {
return this[propName];
}
}
export default Person;
import Person from './person.es6';
const person = new Person('Yamada', 45);
console.log(person.name); // Yamada が出力される
もちろん Setter を用意することもできます。下記の例だと渡された値をそのままセットしてるので private にしている意味がありませんが、本当は値チェックを挟むなど。
const propName = Symbol();
const propAge = Symbol();
/**
* Person class
*/
class Person {
/**
* @constructor
* @param {string} name
* @param {number} age
*/
constructor(name, age) {
this[propName] = name;
this[propAge] = age;
}
/**
* @returns {string}
*/
get name() {
return this[propName];
}
/**
* @param {string} name
* @returns {void}
*/
set name(name) {
this[propName] = name;
}
}
export default Person;
おまけ:private メソッド
コンストラクタ内でメソッド定義しないといけないので微妙ですが.. もしその private メソッドがインスタンス変数にアクセスする必要がない場合は、クラスの外で定義すればよいかもしれません。
const propName = Symbol();
const propAge = Symbol();
const propSomePrivateMethod = Symbol();
/**
* Person class
*/
class Person {
/**
* @constructor
* @param {string} name
* @param {number} age
*/
constructor(name, age) {
this[propName] = name;
this[propAge] = age;
this[propSomePrivateMethod] = () => {
console.log(`こんにちは、${this[propName]}さん。`);
}
}
somePublicMethod() {
// ...
// private メソッドの呼び出し
this[propSomePrivateMethod]();
}
}
export default Person;
ほか余談
-
厳密にいうと
Symbols
を利用したとしても、イテレータか何か(忘れました..)を利用してインスタンスのプロパティにアクセスする手段があったような気がするので、完全に private ではありません。が、そこまで気にしなくてもよいかなという感じです。 -
WebStorm 等の IDE を利用している場合は
@private
アノテーションをつけておけば、外部から利用しようとすると IDE 上で警告を表示してくれます。- 無理して
Symbols
を利用して煩雑になるよりも、現実的にはこれで十分かもしれません^^; メソッドにも@private
アノテーションを付与することができますし。
person.es6/** * Person class */ class Person { /** * @constructor * @param {string} name * @param {number} age */ constructor(name, age) { /** @private */ this.name = name; /** @private */ this.age = age; } } export default Person;
- 無理して
-
素直に TypeScript を使うのがよいかも..