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
Regex Pattern to Match the End of a String
How to Split a String into an Array of Characters
Getting a Unhandledpromiserejectionwarning When Testing Using Mocha/Chai
Unsafe JavaScript Attempt to Access Frame with Url
How to Access Parent Window Object Using Jquery
What Are Alternatives to Extjs
Create a File Using JavaScript in Chrome on Client Side
React React-Router-Dom Pass Props to Component
Where Should Ajax Request Be Made in Flux App
JSON Stringify Changes Time of Date Because of Utc
Chrome Extension: Get Page Variables in Content Script
Checking If Image Does Exists Using JavaScript
JavaScript Triple Greater Than
Does Awaiting a Non-Promise Have Any Detectable Effect
Background-Color Hex to JavaScript Variable