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! 🙂

25 Comments

  • 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

  • Robert Nyman says:

    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.

  • Henrik Hjelte says:

    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.

  • Richard says:

    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.

  • Robert Nyman says:

    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) […]

  • Allen Wirfs-Brock says:

    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

  • Robert Nyman says:

    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.

  • Allen Wirfs-Brock says:

    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

  • Robert Nyman says:

    Allen,

    Yes. However, in my experience,developers in general don't want to choose, they just want a de-facto way of doing it.

  • Mark Willis says:

    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.

  • Robert Nyman says:

    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 help­ful dis­cus­sions on javascript get­ters and set­ters come from John Resig and Robert Nyman. You’ll quickly learn when using get­ters and set­ters they are not defined the same in every […]

  • stephband says:

    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!

  • Robert Nyman says:

    stephband,

    Interesting!

  • Quora says:

    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/…

  • Quora says:

    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…

  • trojani says:

    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’?!

  • Robert Nyman says:

    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 […]

  • Tony says:

    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

  • Tony says:

    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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.