views:

1617

answers:

5

Looking at the mozilla documentation, looking at the regular expression example (headed "Creating an array using the result of a match"), we have statements like:

input: A read-only property that reflects the original string against which the regular expression was matched.

index: A read-only property that is the zero-based index of the match in the string.

etc... is it possible to create your own object in JavaScript which will have read-only properties, or is this a privilege reserved to built-in types implemented by particular browsers?

A: 

I'm not sure what they mean by read-only; I'm able to do this (at least in Safari):

var myRe = /d(b+)(d)/i;
var myArray = myRe.exec("cdbBdbsbz");
myArray.input = 'something else';
alert(myArray.input); // displays 'something else'
JW
var s = "test"; s.length = 200; alert(s.length);
some
@JW: Also in firefox 3 it displays "something else", but then myArry is an array (test with: myArray instanceof Array), and "input" is not an attribute of the native Array.
some
+4  A: 

It is possible to have read-only properties in JavaScript which are available via getter methods. This is usually called the 'Module' pattern.

The YUI blog has a good writeup of it: http://yuiblog.com/blog/2007/06/12/module-pattern/

Snippet from the post:

YAHOO.myProject.myModule = function () {

//"private" variables:
var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule.";

//"private" method:
var myPrivateMethod = function () {
 YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");
}

return  {
 myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty."
 myPublicMethod: function () {
  YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");

  //Within myProject, I can access "private" vars and methods:
  YAHOO.log(myPrivateVar);
  YAHOO.log(myPrivateMethod());

  //The native scope of myPublicMethod is myProject; we can
  //access public members using "this":
  YAHOO.log(this.myPublicProperty);
 }
};

}(); // the parens here cause the anonymous function to execute and return
Ryan Doherty
+8  A: 

In Firefox, Opera 9.5+, and Safari 3+, and Chrome (but not Internet Explorer) 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.

Matthew Crumley
Good one! I tested and it works in Firefox, Opera and Chrome but not IE.
some
an additional note - is this part of any javascript specification?
Claudiu
It's not part of a current spec. I believe it is planned for the next version of ECMAScript, but right now, it's just a Mozilla extension that's supported in a few other browsers.
Matthew Crumley
ah, great, thank you.
Claudiu
and now 2 years later it's in the next spec =)
Claudiu
and still is not supported by IE ;)
Sergiy Byelozyorov
+3  A: 

Here's link to Douglas Crockford's page on "Private Members in Javascript"....it would seem to me these would be read only if only getter methods are supplied, and no setters:

http://javascript.crockford.com/private.html

George Jempty
+1  A: 

With any javascript interpreter that implements ECMAScript 5 you can use Object.defineProperty to define readonly properties. In loose mode the interpreter will ignore a write on the property, in strict mode it will throw an exception.

Example from ejohn.org:

var obj = {};
Object.defineProperty( obj, "value", {
  value: true,
  writable: false,
  enumerable: true,
  configurable: true
});
Aidamina