Is there any way to prevent replacement of JavaScript object properties?

安稳与你 提交于 2019-11-27 16:12:50

问题


I would like to make an object's structure immutable, preventing its properties from being subsequently replaced. The properties need to be readable, however. Is this possible?

I'm sure there are no language features (along the lines of final in Java and readonly in C#) to support this but wondered whether there might be another mechanism for achieving the same result?

I'm looking for something along these lines:

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"; 
};

回答1:


ECMAScript 5 will have seal() and freeze(), but there's no good way to do this with current JavaScript implementations.

Source.




回答2:


the best thing you can do is hide your properties inside of a closure.

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

var f = getMap ();

alert(f.getHidden());

I took a stab at it. In the above code you will need to not just return hidden but copy it into a new object perhaps. maybe you can use jquery's extend to do this for you, so you will be returning a new object, not the reference. This may be completely wrong though =)




回答3:


Using var in an object constructor will create a private variable. This is essentially a closure. Then you can create a public function to access/modify it. More information and examples available on Private Members in Javascript by Douglas Crockford.




回答4:


As mkoryak said, you can create a closure to hide properties

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



回答5:


Okay, so there's been already a couple of answers suggesting you return an object with several getters methods. But you can still replace those methods.

There's this, which is slightly better. You won't be able to replace the object's properties without replacing the function completely. But it's still not exactly what you want.

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" :)



回答6:


You can now force a single object property to be frozen instead of freezing the whole object. You can achieve this with Object.defineProperty and the parameter writable: false

var obj = {
    "first": 1,
    "second": 2,
    "third": 3
};
Object.defineProperty(obj, "first", {
    writable: false,
    value: 99
});

In this example, obj.first now has its value locked to 99.



来源:https://stackoverflow.com/questions/2365318/is-there-any-way-to-prevent-replacement-of-javascript-object-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!