Can Read-Only Properties Be Implemented in Pure JavaScript

Can Read-Only Properties be Implemented in Pure JavaScript?

Edit: Since this answer was written, a new, better way using Object.defineProperty has been standardized in EcmaScript 5, with support in newer browsers. See Aidamina's answer. If you need to support "older" browsers, you could use one of the methods in this answer as a fallback.


In Firefox, Opera 9.5+, and Safari 3+, Chrome and IE (tested with v11) you can define getter and setter properties. If you only define a getter, it effectively creates a read-only property. You can define them in an object literal or by calling a method on an object.

var myObject = {
get readOnlyProperty() { return 42; }
};

alert(myObject.readOnlyProperty); // 42
myObject.readOnlyProperty = 5; // Assignment is allowed, but doesn't do anything
alert(myObject.readOnlyProperty); // 42

If you already have an object, you can call __defineGetter__ and __defineSetter__:

var myObject = {};
myObject.__defineGetter__("readOnlyProperty", function() { return 42; });

Of course, this isn't really useful on the web because it doesn't work in Internet Explorer.

You can read more about it from John Resig's blog or the Mozilla Developer Center.

Defining read-only properties in JavaScript

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.

Is it possible to create read only members in JavaScript Object Literal Notation?

Despite what everyone says, you can create read-only properties in modern browsers that supports Object.defineProperty.

var obj = {};

Object.defineProperty(obj, 'someProp', {
configurable: false,
writable: false,
value: 'initial value'
});

obj.someProp = 'some other value';

console.log(obj.someProp); //initial value

EDIT:

After reading your question again, I understand that you meant true private members or private variables. That can be accomplished by making use of closures and custom getters/setters.

Note: I simplified your object's structure for the sake of the example.

var Parameters = (function () {
var headerType = 'some value'; //private variable

return {
modal_window: {
type: {
normal: function () {
//custom logic
headerType = 'some new value'; //set private variable
}
}
},
header: {
get type() { return headerType; } //define a getter only

//for older browsers, you could just define a normal function
//which you would have to access like Parameters.header.type()
//type: function () { return headerType; }
}
};

})();

var header = Parameters.header;

console.log(header.type); //some value
header.type = 'some other val';
console.log(header.type); //some value
Parameters.modal_window.type.normal();
console.log(header.type); //some new value

Now that we know it is possible to enforce true privacy, I am not sure it's really worth it. Enforcing true privacy complicates the design and reduces testability (depending on the case). An approach that is far popular as well is to simply identify private members using a naming convention such as _myPrivateVar. This clearly indicates the itention and tells the programmers that they should treat that member like a private one.

Object Read-Only Properties

Why is assignment allowed, and if it's allowed, how can nothing happen? In this snippet there is no inferred scope, so I don't understand how something in JS can infer a private property.

Because assignments (before strict mode) never throw and making it throw would violate that invariant that people expect. While you can still override it (by making a setter and making that throw) this is the default behavior in JavaScript for properties. We don't like it but it is what it is.

If you use strict mode - you should get:

TypeError: setting a property that has only a getter

How can you make a variable/Object read only in Javascript?

EDIT: This was writtent 10 years ago. I don't consider this to be an up to date answer.

Realistically... by not overwriting it. You could always control access by wrapping it in an object that only offers GetObj with no SetObj, but of course, the wrapper is equally liable to overwriting, as are its "private" member properties that would be "hidden" via the GetObj method.

Actually, question is a dupe:

Can Read-Only Properties be Implemented in Pure JavaScript?

EDIT:

After reading http://javascript.crockford.com/private.html , it is possible to use closure to create variable references that are truely inaccessible from the outside world. For instance:

function objectHider(obj)
{
this.getObject=function(){return obj;}
}

var someData={apples:5,oranges:4}

var hider=new objectHider(someData);

//... hider.getObject()

where the reference to obj in objectHider cannot be modified after object creation.

I'm trying to think of a practical use for this.

How to make a input field readonly with JavaScript?

You can get the input element and then set its readOnly property to true as follows:

document.getElementById('InputFieldID').readOnly = true;

Specifically, this is what you want:

<script type="text/javascript">
function onLoadBody() {
document.getElementById('control_EMAIL').readOnly = true;
}
</script>

Call this onLoadBody() function on body tag like:

<body onload="onLoadBody">

View Demo: jsfiddle.

Create a read-only/immutable copy of any object (including deep properties)

This is the solution I came up with after some thought. Works well for my needs so I thought I'd share it QnA style.
Do suggest any improvements/issues if you you find them.

/**
* Make the the specified object (deeply) immutable or "read-only", so that none of its
* properties (or sub-properties) can be modified. The converted object is returned.
* @param {object} obj Input object
*/
makeImmutable: function makeImmutable (obj) {
if ((typeof obj === "object" && obj !== null) ||
(Array.isArray? Array.isArray(obj): obj instanceof Array) ||
(typeof obj === "function")) {

Object.freeze(obj);

for (var key in obj) {
if (obj.hasOwnProperty(key)) {
makeImmutable(obj[key]);
}
}
}
return obj;
}

EDIT:
Simplified the code. Also handles arrays correctly now.

Is it possible to create a JavaScript object to not be editable?

One option is to use Object.freeze on the object before returning it, which:

prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed, it also prevents the prototype from being changed.

'use strict';var person = (function() {  var age = "will"
function shoutAge() { console.log(age) }
return Object.freeze({ shoutAge })})();person.shoutAge();person.foo = 'foo';

Is it possible to make input fields read-only through CSS?

With CSS only? This is sort of possible on text inputs by using user-select:none:

.print {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

JSFiddle example.

It's well worth noting that this will not work in browsers which do not support CSS3 or support the user-select property. The readonly property should be ideally given to the input markup you wish to be made readonly, but this does work as a hacky CSS alternative.

With JavaScript:

document.getElementById("myReadonlyInput").setAttribute("readonly", "true");

Edit: The CSS method no longer works in Chrome (29). The -webkit-user-select property now appears to be ignored on input elements.

Set readonly property to false for an HTML text input on clicking an anchor tag

change the readonly property of an element..use prop()

 $("#name").prop('readonly', false);

link to read more about prop() and attr()



Related Topics



Leave a reply



Submit