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! 🙂
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
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.
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.
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.
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.
[…] Getters and setters with JavaScript – code samples and demos (tags: javascript tutorial) […]
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
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.
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
Allen,
Yes. However, in my experience,developers in general don't want to choose, they just want a de-facto way of doing it.
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.
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.
[…] 28: Getters and setters with JavaScript – code samples and demos […]
[…] 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 […]
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!
stephband,
Interesting!
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/…
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…
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’?!
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.
[…] Robert Getters And Setters With JavaScript – Code Samples And Demos […]
Hi Rob,
I really like your javascript articles, the ones on prototypical inheritance, Privileged, Public And Static Members from ’08
I’ve been searching the blog for more goodies like these but it seems like you stopped writing about good old JS.
Please keep writing more engaging articles on JS, you have knowledge that I need 🙂
Cheers
Glad you like them, and that they were helpful! And yes, haven’t been any articles since, and no immediate plans to write more, unfortunately.
Bummer, it’s a loss for the JS community. You obviously know your JS
I appreciate the articles you did write and wish nothing but the best for you.
I’ll keep your blog bookmarked just in case you have a change of heart.
Cheers
Thanks for the kind words! Also, another useful resource is the JavaScript section on MDN, hopefully it has something useful for you!