12

オブジェクトの構造を不変にして、後でそのプロパティが置き換えられないようにしたいと考えています。ただし、プロパティは読み取り可能である必要があります。これは可能ですか?

finalこれをサポートする言語機能 ( Java およびC#の行に沿って) はないと確信していますがreadonly、同じ結果を達成するための別のメカニズムがあるかどうか疑問に思いましたか?

私はこれらの線に沿って何かを探しています:

var o = {
    a: "a",
    f: function () {
        return "b";
    }
};

var p = o.a;        // OK
o.a = "b";          // Error
var q = o.f();      // OK
o.f = function () { // Error
    return "c"; 
};
4

6 に答える 6

14

ECMAScript 5 にはseal()freeze()がありますが、現在の JavaScript 実装でこれを行う良い方法はありません。

ソース

于 2010-03-02T17:43:34.807 に答える
9

あなたができる最善のことは、プロパティをクロージャーの中に隠すことです。

var getMap = function(){
  var hidden = "1";
  return {
    getHidden : function() { return hidden; }
  }
}

var f = getMap ();

alert(f.getHidden());

私はそれを突き刺しました。上記のコードでは、非表示を返すだけでなく、おそらく新しいオブジェクトにコピーする必要があります。おそらく、jquery の拡張を使用してこれを行うことができるので、参照ではなく新しいオブジェクトを返すことになります。これは完全に間違っているかもしれませんが=)

于 2010-03-02T17:40:50.770 に答える
5

varオブジェクトコンストラクターで使用すると、プライベート変数が作成されます。これは本質的に閉鎖です。次に、パブリック関数を作成してアクセス/変更できます。DouglasCrockfordによるJavascriptのプライベートメンバーで利用可能な詳細情報と例。

于 2010-03-02T17:44:50.360 に答える
4

mkoryakが言ったように、プロパティを非表示にするクロージャーを作成できます

function Car(make, model, color) {
    var _make = make, _model = model, _color = color; 

    this.getMake = function() {
        return _make;
    }

}

var mycar = new Car("ford", "mustang", "black");

mycar.getMake(); //returns "ford"
mycar._make; //error
于 2010-03-02T17:44:41.620 に答える
4

さて、いくつかのゲッターメソッドでオブジェクトを返すことを提案する回答がすでにいくつかあります。ただし、これらのメソッドを置き換えることはできます。

これがありますが、これは少し優れています。関数を完全に置き換えないと、オブジェクトのプロパティを置き換えることはできません。しかし、それはまだあなたが望むものではありません。

function Sealed(obj) {
    function copy(o){
        var n = {}; 
        for(p in o){
            n[p] = o[p]
        }
        return n;
    }
    var priv = copy(obj);
    return function(p) {
        return typeof p == 'undefined' ? copy(priv) : priv[p];  // or maybe copy(priv[p])
    }
}

var mycar = new Sealed({make:"ford", model:"mustang", color:"black"});

alert( mycar('make') ); // "ford"
alert( mycar().make );  // "ford"

var newcopy = mycar();
newcopy.make = 'volkwagen';
alert( newcopy.make ); // "volkwagen"  :(

alert( mycar().make );   // still "ford"  :)
alert( mycar('make') );   // still "ford" :)
于 2012-03-06T22:01:48.910 に答える