Skip to content

Instantly share code, notes, and snippets.

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 think49/66c8a8a6589ec3aacc1689ee7d7fddb6 to your computer and use it in GitHub Desktop.
Save think49/66c8a8a6589ec3aacc1689ee7d7fddb6 to your computer and use it in GitHub Desktop.

[JavaScript] プライベートプロパティを作る方法

概要

ECMAScript® 2017 (ES8) にはプライベートプロパティ(private property)、プライベートメソッド(private method)を作る方法が用意されていない為、独自に作る方法を考えます。

コード (Static版)

広く知られる手法は、関数スコープやブロックスコープで括り、内部スコープに変数を定義することです。 (※このコードはインスタンスを複数生成しても、共通参照のプライベートメソッドが呼び出される為、別参照にしたい場合には後述の Instance版を使用する必要があります。)

const Foo1 = (() => {
  function privateStaticMethod (string) {
    console.log(string);
  }

  return class Foo1 {
    bar () {
      privateStaticMethod('Hello, World!');
    }
  };
})();

new Foo1().bar();

コード (Instance版1)

インスタンス毎に独立したプライベートプロパティを定義したコードです。

const Foo2 = (() => {
  var privateMap = new WeakMap;

  return class Foo2 {
    constructor (message) {
      const privateObject = Object.create(null);

      privateObject.message = message;
      privateMap.set(this, privateObject);
    }
    bar () {
      console.log(privateMap.get(this).message);
    }
  };
})();

new Foo2('Hello, World!').bar();
new Foo2('Hello, JavaScript!').bar();

コード (Instance版2)

コード(Instance版1)のプライベートプロパティ参照コードをすっきりさせた版です。

const createPivateMap = () => {
  const wm = new WeakMap;

  return function (key /* [, value] */) {
    return wm.has(key) ? wm.get(key) : wm.set(key, arguments[1]);
  };
};

const Foo3 = (() => {
  var pm = createPivateMap();

  return class Foo3 {
    constructor (message) {
      pm(this, {message: message});
    }
    bar () {
      console.log(pm(this).message);
    }
  };
})();

new Foo3('Hello, World!').bar();
new Foo3('Hello, JavaScript!').bar();

リンク

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment