Getters and setters with JavaScript – code samples and demos
Not many people know it, but you can use “real” getters and setters in JavaScript if you want to.
De-facto offerings
Firefox 2.0+, Safari 3.0+, Google Chrome 1.0+ and Opera 9.5+ support a de-facto way of getters and setters:
var lost = { loc : "Island", get location () { return this.loc; }, set location(val) { this.loc = val; } }; lost.location = "Another island"; // lost.location will now return "Another island"
And on DOM elements:
HTMLElement.prototype.__defineGetter__("description", function () { return this.desc; }); HTMLElement.prototype.__defineSetter__("description", function (val) { this.desc = val; }); document.body.description = "Beautiful body"; // document.body.description will now return "Beautiful body";
Via Object.defineProperty
The future, and ECMAScript standardized way, of extending objects in all sorts of ways is through Object.defineProperty
. This is how Internet Explorer chose to implement getters and setters, but it is unfortunately so far only available in Internet Explorer 8, and not in any other web browser. Also, IE 8 only supports it on DOM nodes, but future versions are planned to support it on JavaScript objects as well.
Getter and setters in IE8+:
Object.defineProperty(document.body, "description", { get : function () { return this.desc; }, set : function (val) { this.desc = val; } }); document.body.description = "Content container"; // document.body.description will now return "Content container"
Test cases
I’ve put together test cases in my JavaScript test site, where you can see JavaScript web browser compatibility tables and code samples and demos for getters and setters together with Object.defineProperty
.
Conclusion
Kudos for Microsoft to take the step to implement Object.defineProperty
, although it’s sad that it’s only available for DOM elements as of now. Also, just as we have consistency between web browsers with innerHTML
, XMLHTTPRequest
etc, it would have been really desirable if Microsoft would have supported the several years-old de-facto way of implementing getters and setters.
So, Microsoft slowly treads forward, which is good, but at the same unfortunately gives us yet another case of doing something different to make it work in Internet Explorer (more about this can be read in ECMAScript getters and setters interoperability).
Anyway, getters and setters are here today, and with some feature detection, you can use it to implement some nice things. Happy coding!
20 Comments
May 28th, 2009 at 21:20
Hi Robert, it is not only DOM, it is the global Window object as well
In any case, since other browsers implements define[G|S]etter since ages, it is possible to replicate both behaviors normalizing a bit the panorama.
Regards
May 28th, 2009 at 22:58
Andrea,
Good point about the <code>window</code>.
Nice concept, one can definitely normalize the usage of it. Here, I just wanted to present the concept and let people know about what we have to deal with.
May 29th, 2009 at 18:19
Syntactic sugar. Not backwards compatible. Why keep making the language bigger with meaningless things like this? If this continues one day we will wake up and discover that Javascript is not the small flexible language anymore, it is bloated and the pocket reference doesn't fit into the pocket anymore. Please stop.
May 29th, 2009 at 19:04
One thing to keep in mind when using this. It should be only be used for encapsulation inside of an object. Meaning if you need to access a variable inside another js "object" then use this. Otherwise it is a waste of CPU cycles. Don't inflate your code for no reason.
May 30th, 2009 at 1:14
Henrik,
Well, yes and no. I agree that JavaScript should be kept small, but it's also about making it easy for new adopters to understand and use javaScript in the best possible way.
Richard,
Don't really have any performance tests on this, but it's also about being able to write JavaScript code as you would do in other languages. So, there are more factors that play into role here.
May 31st, 2009 at 14:05
[...] Getters and setters with JavaScript – code samples and demos (tags: javascript tutorial) [...]
June 18th, 2009 at 21:24
Robert,
IE8 getter/setter support is directly based upon what is being standardized in ECMAScript 5. The ECMAScript committee (which includes participants from all the major browser vendors) explictly decided to use this new getter/setter design over the __defineGetter__/__defineSetter__ alternative. See the rationale document for an explanation of the thinking behind the new design.
Another reason for choosing a new API for a feature like this is that while several browser support the __defineX__ API there are actually subtle semantic variations among the various implementations. One of the jobs of a standard is to iron out these differences, but the end result of this is that at least some, if not all existing implementation need to change to conform to the standard. By using a new API, the legacy non-standard APIs can be preserved by existing implementation providing full compatability for existing code that depends upon them.
Allen Wirfs-Brock
Microsoft
June 19th, 2009 at 0:00
Allen,
Absolutely, and it's good to have that standardization. What I mean, though, is that perhaps Internet Explorer could have offered both, to get the result of the same (or almost, as you point out) looking code for all web browser, and there could be a future code branching for the standardized approach.
Personally, I think as it is now, very few people will use getters and setters, just because they deem it a hassle.
June 19th, 2009 at 20:02
One consideration was that once a feature (for example, __defineX__) exists in all major browsers it is almost impossible to get rid of it, even if there is a better standardize alternative.
Eventually all browsers will support Object.defineProperty and the hassle will go away. In the meantime, it is trivial to define __defineX__ methods in terms of Object.defineProperty or to define an equivalant functionality subset of Object.defineProperty using __defineX__ methods. This makes it pretty easy for applicaiton developers to choose to use whichever API they prefer in the body of their code.
Allen Wirfs-Brock
Microsoft
June 19th, 2009 at 21:06
Allen,
Yes. However, in my experience,developers in general don't want to choose, they just want a de-facto way of doing it.
August 26th, 2009 at 22:06
What's the point! How can I use getters/setters when Microsoft uses a different mechanism than the rest of the world. My opinion from reading the rational document is that JavaScript was so poorly designed they are now having difficulties implementing something that should be simple.
August 26th, 2009 at 22:10
Mark,
Well, for library developers and others, it might be a good way to control code. But I agree, for the everyday-developer, it's not that interesting until it works the same way across web browsers.
December 30th, 2009 at 0:34
[...] 28: Getters and setters with JavaScript – code samples and demos [...]
October 5th, 2010 at 6:13
[...] two most helpful discussions on javascript getters and setters come from John Resig and Robert Nyman. You’ll quickly learn when using getters and setters they are not defined the same in every [...]
November 11th, 2010 at 15:18
Just thought I’d point out that IE9 now supports the ‘De-facto’ method of declaring getters and setters.
var obj = {
get thing(){},
set thing(){}
};
Yahay!
November 15th, 2010 at 12:58
stephband,
Interesting!
September 29th, 2011 at 14:54
How are object getters and setters used in JavaScript?…
Robert Nyman explains them better here, http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/…
October 10th, 2011 at 2:57
How are object getters and setters used in JavaScript?…
UPDATE: In my post, below, I claim that get and set are not legal operators in Javascript. Actually, it depends on which version you’re using. They are legal in ECMAScropt 5 (as Rick Waldron and Andy Farrell pointed out). This is the most recent versi…
January 29th, 2012 at 23:29
var lost = {loc : “Island”} //done: lost.loc >> Island
lost.loc = “my Island” //Done!
document.body.description = “Beautiful body”; //done!
What getter [?!] -what setter [!! ?]
This is Java Script sunny, and its a live and pure.
p.s: wtf ‘setter’?!
January 30th, 2012 at 10:31
trojani,
It’s not about just setting values, it’s about controlling how they are applied/changed and to be more in line with other programming languages.
Write a comment