0

私は次のJavaScriptオブジェクトリテラル通知オブジェクトを持っています

var Parameters= {
    modal_window:{
        backdrop:true,
        keyboard:true,
        show:true,
        remote:false,
        type:{
            normal:function(){
                this.footer.button.accept.type='btn btn-primary';
                this.header.type='modal-header';
            },
            success:function(){
                this.footer.button.accept.type='btn btn-success';
                this.header.type='modal-header alert alert-success';
            },
            info:function(){
                this.footer.button.accept.type='btn btn-info';
                this.header.type='modal-header alert alert-info';
            },
            error:function(){
                this.footer.button.accept.type='btn btn-danger';
                this.header.type='modal-header alert alert-error';
            },
            warning:function(){
                this.footer.button.accept.type='btn btn-warning';
                this.header.type='modal-header alert';
            }
        }
    },
    header:{
        title:undefined,
        type:this.window.type.normal.header
    },
    footer:{
        button:
        {
            accept:{
                title:'Accept',
                click:undefined,
                type:undefined
            },
            cancel:{
                title:'Cancel',
                click:undefined
            }
        }
    }
};

header.type と footer.button.accept.type を、window.type.normal、window.type.success などでのみ変更できる読み取り専用変数にすることはできますか?

明確化: ここでいくつか明確化したいと思います。私の Parameters.header.type は読み取り専用で、デフォルト値を持つ必要があります。たとえば、ユーザーが Parameters.modal_window.type.normal を選択すると、Parameters.header.type を変更する必要があります。

4

7 に答える 7

2

IE 8 以前をサポートする必要がある場合は、値を取得するアクセサー メソッドを作成し、プライベート変数を使用して実際のデータを格納することができます。メソッドを適切に定義すると、それらからプライベート変数を設定できますが、外部から設定することはできません。IE8 では、読み取り専用プロパティを定義する機能がないため、代わりにアクセサーを使用する必要があります。

アクセサーがインターフェイスになるプライベート データを設定する方法の詳細については、プライベート メンバー データに関する Crockford の論文 ( http://javascript.crockford.com/private.html ) を参照してください。

IE9 以上を必要とする場合Object.defineProperty()は、クロージャでプライベート変数と組み合わせて getter を使用できます。セッターが存在しない場合、外部から設定することはできませんが、クロージャー内で定義されたメソッド (Crockford の記事で説明) は、プライベート変数の値を設定できます。いくつかの独自のメソッドによっても設定できる読み取り専用プロパティがあります。

于 2013-11-02T17:32:45.737 に答える
2

次のように機能させることができます。

header:{
        title:undefined,
        type: function(){
           return Parameters.modal_window.type.normal.header;
        }
    }
于 2013-11-02T17:31:22.640 に答える
2

プロパティを作成して、書き込み不可に設定できます。コンストラクターは、値をプロパティに置き換える必要があります。プロパティが返す変数がクロージャに取り込まれ、他に公開されていない場合、読み取り専用と同じになります。変更されていない場合は、クロージャーも必要ありませんvalue。構成オプションを使用するだけです。

編集:あなたの要求に従って、

var Properties = function(obj) {
    var makePropRecursive = function(prop) {
        var old_prop = obj[prop];
        delete obj[prop];
        var prop_obj = {};
        for (var attr in old_prop) {
            if (old_prop.hasOwnProperty(attr)) {
                Object.defineProperty(prop_obj, attr, {
                    value: old_prop[attr],
                    writable: false,
                    enumerable: true
                });
            }
        }
        Object.defineProperty(obj, prop, {
            value: prop_obj,
            writable: false,
            enumerable: true
        });
    };
    makePropRecursive('header');
    makePropRecursive('footer');
    return obj;
};

var props = new Properties({
    modal_window:{
        backdrop:true,
        keyboard:true,
        show:true,
        remote:false,
        type:{
            normal:function(){
                this.footer.button.accept.type='btn btn-primary';
                this.header.type='modal-header';
            },
            success:function(){
                this.footer.button.accept.type='btn btn-success';
                this.header.type='modal-header alert alert-success';
            },
            info:function(){
                this.footer.button.accept.type='btn btn-info';
                this.header.type='modal-header alert alert-info';
            },
            error:function(){
                this.footer.button.accept.type='btn btn-danger';
                this.header.type='modal-header alert alert-error';
            },
            warning:function(){
                this.footer.button.accept.type='btn btn-warning';
                this.header.type='modal-header alert';
            }
        }
    },
    header:{
        title:"Whatever",
        type:"Type"
    },
    footer:{
        button:
        {
            accept:{
                title:'Accept',
                click:undefined,
                type:undefined
            },
            cancel:{
                title:'Cancel',
                click:undefined
            }
        }
    }
});

console.log(props.header);
props.header = 17;
props.header.type = 18;
props.header.title = 19;
console.log(props.header);

props.header変更されていません: 出力が表示されます

Object {title: "Whatever", type: "Type"}
Object {title: "Whatever", type: "Type"} 

今は午前 3 時ですが、再帰関数はそうではないため、1 つのオブジェクトの 1 つのレベルのみを「修正」できます。thisまた、値を返すのではなくコピーしたほうがよいでしょうobj。しかし、それを磨くのは難しくありません。

値を変更可能にする必要がある場合は、コンストラクター内にオブジェクト全体のプライベート コピーを設定してから、getter ( get: function(name) { return stuff.from.the.original.object }) を作成できます。

于 2013-11-02T17:35:14.910 に答える
1

次の公開モジュール パターンを使用して変数を非表示にし、それらが変更されないようにすることができますが、アクセス可能な「型」関数を変更することはできません。

以下のコードでは、header プロパティを _header に変更し、関数にしました。プロパティの型は _type に変更され、プロパティではなく関数として "type" を返すオブジェクト表記で return をラップすることで非表示になりました。type 関数を上書きして好きなように変更することはできますが、_type の値を変更することはできません。

var Parameters = function () {
var _modal_window = function modal_window() {
    var backdrop = true,
    keyboard = true,
    show = true,
    remote = false;
    return {
        type: {
            normal: function () {
                this.footer.button.accept.type = 'btn btn-primary';
                this.header.type = 'modal-header';
            },
            success: function () {
                this.footer.button.accept.type = 'btn btn-success';
                this.header.type = 'modal-header alert alert-success';
            },
            info: function () {
                this.footer.button.accept.type = 'btn btn-info';
                this.header.type = 'modal-header alert alert-info';
            },
            error: function () {
                this.footer.button.accept.type = 'btn btn-danger';
                this.header.type = 'modal-header alert alert-error';
            },
            warning: function () {
                this.footer.button.accept.type = 'btn btn-warning';
                this.header.type = 'modal-header alert';
            }
        }
    };
}();
var _header = function header() {
    var _type = 'This causes error';//this.window.type.normal.header;
    return {
        title: undefined, type: function () { return _type; }
    };
}();
var _footer = function footer() {
    return {
        button:
    {
        accept: {
            title: 'Accept',
            click: undefined,
            type: undefined
        },
        cancel: {
            title: 'Cancel',
            click: undefined
        }
    }
    };
}();
return {
    modal_window: _modal_window,
    header: _header,
    footer: _footer
};
}();
于 2013-11-02T18:39:05.500 に答える