LoginSignup
25
23

More than 5 years have passed since last update.

オライリー本「JavaScriptパターン」で紹介されてるプライベートプロパティ(メンバ)は、インスタンス変数じゃなくてクラス変数

Last updated at Posted at 2013-09-23

オライリーの「JavaScriptパターン」で、コンストラクタを使って生成したインスンタンスでプライベートメンバ(プロパティ)を実現する方法が2つほど紹介されている。

  • P98. 「5.3.5 プロトタイプとプライバシー」
  • P103. 「5.4.2 コンストラクタを作成するモジュール」

この「プライベートメンバ(プロパティ)」は、 Java でいうところのインスタンス変数ではなく、クラス変数と同じ振る舞いをする。

本をよく読むと、確かに以下のように書いてある。

  • P98

この方法によって同じコンストラクタで作成されたインスタンスはすべて 共通する部分を共有できる ようになります。

危うくインスタンス変数だと勘違いしたまま使うところだった。。。

検証

「5.3.5 プロトタイプとプライバシー」で紹介されている方法

サンプル:http://jsfiddle.net/opengl_8080/CRG7P/

function MyClass(name) {
    this.name = name;
}

MyClass.prototype = (function(){
    var message;

    return {
        getMessage: function() {
            return this.name + '' + message + '';
        },
        setMessage: function(value) {
            message = value;
        }
    };
}());

var hoge = new MyClass('hoge');
hoge.setMessage('嘘だ・・・インスタンス変数だろ・・・これ・・・インスタンス変数に決まってる・・・!');
console.log(hoge.getMessage());

var fuga = new MyClass('fuga');
fuga.setMessage('ところがどっこい・・・インスタンス変数じゃありません・・・!  クラス変数です・・・! これが現実・・・!');

console.log(hoge.getMessage());
実行結果
hoge「嘘だ・・・インスタンス変数だろ・・・これ・・・インスタンス変数に決まってる・・・!」
hoge「ところがどっこい・・・インスタンス変数じゃありません・・・! クラス変数です・・・! これが現実・・・!」

「5.4.2 コンストラクタを作成するモジュール」で紹介されている方法

サンプル:http://jsfiddle.net/opengl_8080/r4FFR/

var MyClass = (function(){
    var _message;

    var Constr = function(name) {
        this.name = name;
    };

    Constr.prototype = {
        setMessage: function(message) {
            _message = message;
        },
        getMessage: function() {
            return this.name + '' + _message + '';
        }
    };

    return Constr;
}());

var hoge = new MyClass('hoge');
hoge.setMessage('もしかしてクラス変数ですかーッ!?');
console.log(hoge.getMessage());

var fuga = new MyClass('fuga');
fuga.setMessage('YES! YES! YES! "OH MY GOD"');

console.log(hoge.getMessage());
実行結果
hoge「もしかしてクラス変数ですかーッ!?」
hoge「YES! YES! YES! "OH MY GOD"」

じゃあ、どうすればプライベートなインスタンスメンバを定義できるのか?

インスタンスの数が少ないことが予想される場合

 → コンストラクタ関数にプライベートメンバも特権メソッドも全部書く。

function MyClass() {
    var privateMember;

    this.getPrivateMember = function() {
        return privateMember;
    };
}

インスタンス数が多くなることが予想される場合

 → 諦めて全部 public にする。

そもそも、言語仕様で private がサポートされてないのだから、潔く全部 public にすべきなのかもしれない。

参考

25
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
23