Defining read-only properties in JavaScript

Given an object obj, I would like to define a read-only property 'prop' and set its value to val. Is this the proper way to do that?

Object.defineProperty( obj, 'prop', {
    get: function () {
        return val;
    }
});

The result should be (for val = 'test'):

obj.prop; // 'test'
obj.prop = 'changed';
obj.prop; // still 'test' since it's read-only

This method works btw: http://jsfiddle.net/GHMjN/
I'm just unsure if this is the easiest / smoothest / most proper way to do it...

Answers:

Answer

You could instead use the writable property of the property descriptor, which prevents the need for a get accessor:

var obj = {};
Object.defineProperty(obj, "prop", {
    value: "test",
    writable: false
});

As mentioned in the comments, the writable option defaults to false so you can omit it in this case:

Object.defineProperty(obj, "prop", {
    value: "test"
});

This is ECMAScript 5 so won't work in older browsers.

Answer

In new browsers or node.js it is possible to use Proxy to create read-only object.

var obj = {
    prop: 'test'
}

obj = new Proxy(obj ,{
    setProperty: function(target, key, value){
        if(target.hasOwnProperty(key))
            return target[key];
        return target[key] = value;
    },
    get: function(target, key){
        return target[key];
    },
    set: function(target, key, value){
        return this.setProperty(target, key, value);
    },
    defineProperty: function (target, key) {
        return this.setProperty(target, key, value);
    },
    deleteProperty: function(target, key) {
        return false;
    }
});

You can still assign new properties to that object, and they would be read-only as well.

Example

obj.prop
// > 'test'

obj.prop = 'changed';
obj.prop
// > 'test'

// New value
obj.myValue = 'foo';
obj.myValue = 'bar';

obj.myValue
// > 'foo'
Answer

Because of the old browsers (backwards compatibility) I had to come up with accessor functions for properties. I made it part of bob.js:

var obj = { };
//declare read-only property.
bob.prop.namedProp(obj, 'name', 'Bob', true);
//declare read-write property.
bob.prop.namedProp(obj, 'age', 1);

//get values of properties.
console.log(bob.string.formatString('{0} is {1} years old.', obj.get_name(), obj.get_age()));
//set value of read-write property.
obj.set_age(2);
console.log(bob.string.formatString('Now {0} is {1} years old.', obj.get_name(), obj.get_age()));

//cannot set read-only property of obj. Next line would throw an error.
// obj.set_name('Rob');

//Output:
//========
// Bob is 1 years old.
// Now Bob is 2 years old.

I hope it helps.

Answer

I tried and it Works ...

element.readOnly = "readOnly"  (then .readonly-> true)
element.readOnly = ""  (then .readonly-> false)

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.