Changes between Version 11 and Version 12 of HowTo/JavaScriptLanguageIntroduction


Ignore:
Timestamp:
Aug 1, 2010, 10:24:53 PM (14 years ago)
Author:
村山 俊之
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • HowTo/JavaScriptLanguageIntroduction

    v11 v12  
    329329}}}
    330330
     331最後に、メンバの private 宣言に相当するアクセス制約についてですが、 !JavaScript にその為の簡潔な記法が用意されているわけではないものの、それに近いものをクロージャを用いて実現することは可能である、という例を以下に示します。ここまでやるとかなり大きなグループ開発にも耐えうる運用となり得ますが、 !JavaScript 界隈ではあまり見かけない習慣かも知れません。
     332
     333{{{
     334var IS_DEBUG = true;
     335
     336function Human(name, birth, sex) {
     337    // プライベートフィールド
     338    var fields = {
     339        "name": name,
     340        "birth": birth instanceof Date ? birth : new Date(birth),
     341        "sex": /^m/i.test(sex) ? "male" : "female"
     342    };
     343   
     344    // メソッドがプライベートフィールドを参照するためのメソッド
     345    this.getFields = function() {
     346        if (IS_DEBUG && !this.permitPrivate())
     347            throw new Error("private method access denied.");
     348        return fields;
     349    };
     350}
     351
     352Human.prototype = {
     353    // プライベートメソッドの呼び出し元をチェックしてアクセス許可を判定する
     354    "permitPrivate": function() {
     355        var is_permitted = false;
     356        for (var method in Human.prototype) {
     357            if (Human.prototype[method] == arguments.callee.caller.caller) {
     358                is_permitted = true;
     359                break;
     360            }
     361        }
     362        return is_permitted;
     363    },
     364    // private:
     365    "getAge": function() {
     366        if (IS_DEBUG && !this.permitPrivate())
     367            throw new Error("private method access denied.");
     368        var now = new Date();
     369        var today = now.getFullYear() + ("0" + (now.getMonth() + 1)).slice(-2) +
     370            ("0" + now.getDay()).slice(-2);
     371        var birth = this.getFields().birth;
     372        var birth_day = birth.getFullYear() + ("0" + (birth.getMonth() + 1)).slice(-2) +
     373            ("0" + now.getDay()).slice(-2);
     374        return (today - birth_day) / 10000 | 0;
     375    },
     376    // public:
     377    "introduce": function() {
     378        var fields = this.getFields();
     379        alert("私の名前は" + fields.name + "。" +
     380            fields.birth.getFullYear() + "年" + (fields.birth.getMonth() + 1) + "月" +
     381            fields.birth.getDay() + "日生まれの" + this.getAge() + "歳・" +
     382            (fields.sex == "male" ? "男性" : "女性") + "です。");
     383    }
     384};
     385
     386var murachi = new Human("村山 俊之", new Date(1978, 1, 7), "male");
     387
     388murachi.introduce();            // 紹介文を表示
     389alert(murachi.getAge() + "歳"); // エラー: プライベートメソッドにアクセスできない
     390}}}