自己呼び出し関数と呼び出しの使用
JavaScript はプロトタイプを使用し、オブジェクト指向言語のようなクラス (またはメソッド) を持ちません。JavaScript 開発者は JavaScript で考える必要があります。
ウィキペディアの引用:
多くのオブジェクト指向言語とは異なり、関数定義とメソッド定義の間に区別はありません。むしろ、関数の呼び出し中に区別が発生します。関数がオブジェクトのメソッドとして呼び出されると、関数のローカルな this キーワードがその呼び出しのためにそのオブジェクトにバインドされます。
自己呼び出し関数と呼び出し関数を使用してプライベート「メソッド」を呼び出すソリューション:
var MyObject = (function () {
// Constructor
function MyObject(foo) {
this._foo = foo;
}
function privateFun(prefix) {
return prefix + this._foo;
}
MyObject.prototype.publicFun = function () {
return privateFun.call(this, ">>");
}
return MyObject;
}());
var myObject = new MyObject("bar");
myObject.publicFun(); // Returns ">>bar"
myObject.privateFun(">>"); // ReferenceError: private is not defined
call 関数を使用すると、適切なコンテキストでプライベート関数を呼び出すことができます ( this
)。
Node.js でよりシンプルに
Node.jsを使用している場合は、モジュール ローディング システムを利用できるため、 IIFEは必要ありません。
function MyObject(foo) {
this._foo = foo;
}
function privateFun(prefix) {
return prefix + this._foo;
}
MyObject.prototype.publicFun = function () {
return privateFun.call(this, ">>");
}
module.exports= MyObject;
ファイルをロードします。
var MyObject = require("./MyObject");
var myObject = new MyObject("bar");
myObject.publicFun(); // Returns ">>bar"
myObject.privateFun(">>"); // ReferenceError: private is not defined
(new!) 将来の JavaScript バージョンのネイティブ プライベート メソッド
TC39プライベート メソッドと JavaScript クラスのゲッター/セッターの提案はステージ 3 です。つまり、近いうちに、JavaScript がプライベート メソッドをネイティブに実装することになります。
JavaScript プライベート クラス フィールドは、最新の JavaScript バージョンに既に存在することに注意してください。
使用方法の例を次に示します。
class MyObject {
// Private field
#foo;
constructor(foo) {
this.#foo = foo;
}
#privateFun(prefix) {
return prefix + this.#foo;
}
publicFun() {
return this.#privateFun(">>");
}
}
このコードを古い JavaScript エンジンで実行するには、 JavaScript トランスパイラー/コンパイラーが必要になる場合があります。
#
PS:プレフィックスの理由が気になる場合は、こちらをお読みください。
(非推奨) Bind Operator を使用した ES7
警告: バインド オペレーター TC39 の命題はほぼ死んでいます https://github.com/tc39/proposal-bind-operator/issues/53#issuecomment-374271822
bind オペレーター::
は ECMAScript の提案であり、Babel で実装されています(ステージ 0 )。
export default class MyObject {
constructor (foo) {
this._foo = foo;
}
publicFun () {
return this::privateFun(">>");
}
}
function privateFun (prefix) {
return prefix + this._foo;
}