Thursday, November 24th, 2005

Getters and Setters in JavaScript

Category: JavaScript

<p>Some of us have been developing in an environment where JavaScript 1.5 is available.

One of the small but cool features that you really miss when you get back to the real world of supporting legacy browsers, is getter and setters.

Getters and Setters are all about encapsulating field access. They are similar to .NET rather than Java. Java has get and set methods that follow conventions rather than seemlessly hiding the interface.

In Java you see:

o.getFoo()
o.setBar()

and if you tried:

o.foo
o.bar

it is a very different thing.

JavaScript does it right (as do a lot of platforms), and the user of a property doesn’t have to know if it is a simple field access or not.

The magic is encapsulated with the get and set keywords placed before a method:

o = { 
  a:7, 
  get b() { return this.a+1; }, 
  set c(x) { this.a = x/2 } 
};
o.a
=== 7
o.b
=== 8
o.c = 50
o.a
=== 25

In the Mozilla implementation you can get access via magic __defineGetter__ and __defineSetter__ methods.

For example, here we augment the standard Date object:

var d = Date.prototype;
d.__defineGetter__("year", function() { return this.getFullYear(); });
d.__defineSetter__("year", function(y) { this.setFullYear(y); });

Posted by Dion Almaer at 1:29 am
7 Comments

+++--
3.3 rating from 24 votes

7 Comments »

Comments feed

Yep… this is an almost exact copy from the devmo (mozilla developer) JS documentation. What I can’t find there however is how do you define getters and setters in a constructor function (or using the .prototype form)?

Because it’s quite rare (I think) to declare a concrete object out of the (or into the :) ) blue. But usually we create classes (i.e. multiple instances of the same object). But this form only works concrete object creation.

Comment by atleta — November 24, 2005

This may come out a bit harsh, due in part to the late hour. I always find it a bit unfortunate when influential blogs mention powerful concepts like these, though, without a context of when or how they can be put to good use, rather than making code harder to read, understand and debug, or less portable, as is the case in these two examples.

First, by changing the expected results of a few very basic lines of code that surface wise seem not to do any destructive changes on a, then by changing the semantics of base language parts, which serves to make your code blend worse with code not invented here.

Used right, they are powerful tools that can be put to use to maintain backwards compatibility with archaic APIs you otherwise would have had to leave behind, for instance. – Without making those parts of the code added for the legacy support add much clutter to your code base, nonetheless.

Comment by Johan Sundström — November 24, 2005

Good pointer. I guess this is not supported in IE? I tried it with Rhino 1.6R2 and it is not supported there. Is this part of the standard BTW?

Comment by Jun Yang — November 30, 2005

Last I checked, Microsoft’s JScript (or IE) ECMA implementation does not support setters and getters in any form.

During object construction, one of two approaches may be used, obviously since you can do this in the prototype exactly as the syntax above, since an object prototype is simply an object itself.

In order to provide lexical access to local data in a constructor itself (aka. private data), below is an example of both approaches:

function Constructor () {
var foo = []

this.length getter = function () {
return foo.length
}
}
Constructor.prototype = {
publicList: [],

get publicLength () {
return this.publicList.length
}
}

This way you can dynamically set the getter or setter of any property.

As far as being a part of a specification, this was originally extracted from the ESR4 proposal, which also adds a bunch of unneccesary crap…but this is one of the useful features it adds :-) It’s true that rhino should support this but it doesn’t, patches are welcome.

This web application could use some advanced formatting.

Comment by Scott McCoy — December 1, 2005

Is there any way to test whether a method is a getter or setter?

Comment by Daniel Higginbotham — December 18, 2006

Find a modular homes builder to construct your dream home.

Comment by Modular Homes — June 12, 2007

>Constructor.prototype = {
>publicList: [],
>
>get publicLength () {
>return this.publicList.length
>}
>}

I think, that better don’t write getters like this. May be it works, but code is smelling…

Comment by Victor Nazarov — July 13, 2007

Leave a comment

You must be logged in to post a comment.